KMP算法中的next数组求解

KMP算法是在模式串的next数组基础上进行的,如何求解next数组就成了关键。

next数组的求解和主串无关,只与模式串自身相关。

则next[j]=

           -1, 当j=0时

           Max {k|0

           0,其他情况

比如对于p[5]=c, next[5]=2,因为'p0p1'='p3p4',此时k=2。

下面参考《数据结构》严蔚敏书中的方法,介绍求解next数组的递推方法。

根据上述定义,next[0]=-1.

设next[j]=k,则根据定义有下列关系式成立:

                      'p0,...,pk-1' = 'pj-k,...,pj-1'

其中k为满足0

那么next[j+1]=?

(1)如果pk = pj,即p[j]=p[next[j]] 则表明:

                   'p0,...,pk-1,pk' = 'pj-k,...,pj-1,pj'

则next[j+1]=next[j]+1.

比如考虑模式串p=abcabcabd,(假设数组下标从0开始),假设已经求得next[0~4],现在要求next[5]。

p        a    b   c   a   b     a   b   d  

next   -1   0   0   0  1

j          0   1   2   3  4   5   6   7   8

那么next[5]=next[4]+1=2。因为p[j]=p[next[4]]=p[k].此时的j=4,k=next[j]=1.

(2)如果pk != pj,即p[j] != p[next[j]],则表明:

                      'p0,...,pk-1,pk' = 'pj-k,...,pj-1,pj'                                          

但有

                      'p0,...,pk-1' = 'pj-k,...,pj-1'

此时可以把求解next数组看成是一个模式匹配的问题,整个模式串即是主串又是模式串。

根据'p0,...,pk-1' = 'pj-k,...,pj-1',在pk和pj处遇到了不想等的情况,此时应当模式串“向右滑动至以模式串中的第next[k]个字符和主串中的第j个字符相比较(主串不回溯)”。若next[k]=k',且pj = pk',则说明主串中第j+1个字符之前存在一个长度为k'(代替情况(1)中的k)的最长字串,和模式串中从首字符其长度为k'的字串相等,即:

                       '0,...,pk-1,pk' ' = 'pj-k,...,pj-1,pj'  (这里和情况(1)相比,用k'代替了k)

这就是说,next[j+1]=k'+1=next[k]+1.

同理,如果pj != pk',则应该将模式串继续向右滑动,直至将模式串中第next[k']个字符串和pj对齐。......以此类推,直至pj和模式串中的某个字符匹配成功或者不存在任何k'满足 '0,...,pk-1,pk' ' = 'pj-k,...,pj-1,pj'  ,此时next[j+1] = 0.

比如考虑p=abaabcac,已知求得next[0~5],现在要求next[6].

p           a    b   a   a   b   c   a   c 

next      -1   0   0   1   1   2 

j            0    1   2   3   4   5   6  7

现在要求next[6],因为next[5]=2,又p2 != p5,则需要继续比较p5 和p[next[2]]即比较p5和p0,这相当于向右滑动模式串;又p5 != p0,且next[0]=-1,所以next[6]=0.

你可能感兴趣的:(初识算法)