KMP next数组理解

3.15周末学长教了一下KMP,但是对next的构造尚存疑.在饶了一整天头以后勉强弄懂了…记录一下比较混乱就是了…

将next数组记录的值看作是对称程度

这里的对称指的的字符块对称而非轴对称;

--------->当next[t]值为0时:
显然就意味着从字符串的开头到这个t部分的话对称性是0:即当继续计算下一位的next[t+1] 的大小时只需比较第n+1位的字符与首字符是否相同即可


--------->当next[t]值不为0时:
这个时候就说明从字符串的开头到这个t部分的话存在对称字符我们假设next[t]的值是a,那么就说明前a个字符与后a个字符是相同的.我们计算next[t+1]时就只需要比较第a+1的字符与t+1的字符是否一致


  1. 当这两个字符相同时,显然,我们只需要令next[t+1]=next[t]+1即可
  2. 当这两个字符不相同时
    这里先放一个大佬码的完整代码
 void makeNext(const char P[],int next[]) 
   { 
       int q,k;//q:模版字符串下标;k:最大前后缀长度 
       int m = strlen(P);//模版字符串长度 
            next[0] = 0;//模版字符串的第一个字符的最大前后缀长度为0 
                 for (q = 1,k = 0; q < m; ++q)//for循环,从第二个字符开始,依次计算每一个字符对应的next值 
                 { 
                     while(k > 0 && P[q] != P[k])//递归的求出P[0]···P[q]的最大的相同的前后缀长度k 
                         k = next[k-1];          //不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解 
                     if (P[q] == P[k])//如果相等,那么最大相同前后缀长度加111                                  
                     {
                         k++;
                     }
                      next[q] = k;
                  }
       }

相当于就是解释一下这段语句的含义在这里插入图片描述
先看这几个字母的定义
k:最大相同前后缀长度
P:输入的要建next数组的字符串
q:要建立next数组的下标


while(k > 0 && P[q] != P[k]):
这个很好理解,注意一下这个时候的k在没有进行while循环时存储的是在q-1个字符中的最大相同前后缀
意思就是如果没有相同的前后缀了或者第k+1(因为next是从o开始建的)和第q个相同时我们就跳出


然后我们来分析一下:k = next[k-1];
这段代码可以说是核心了
首先要进行这段语句的前提:
k > 0 && P[q] != P[k].首先要尚存相同的前后缀,如果已经没有相同前后缀时,直接跳出给next[q]赋0就ok.并且P[q] != P[k].
紧接着看这个语句的意义:,我们仍然从第一次进入while循环分析:
这里k本来是指q之前的字符串最大前后缀长度,因为第q个字符和第k+1个字符不相同,我们再继续找这最大前后缀长度包括的最大的前后缀长度,并且这样循环的比较下去.知道发现能构成一个新的最大前后缀长度或者是干脆构不成.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljw0925

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值