KMP算法next数组计算的理解——菜鸟福音

我的文章莫名找不到了。。。还是再写一遍吧,希望对了解KMP的算法有点帮助……

首先写几点
1)本文讨论的KMP主要是严蔚敏的《数据结构》中第四章提到的KMP,即带NEXT[]辅助数组的KMP算法
2)本文主要是讨论KMP算法NEXT[]数组的计算的理解,一些数学上不严谨的地方还请见谅
3)本文主要针对算法及数据结构的新手,希望能帮助大家快速理解KMP

KMP算法在网络到处都是讨论,在这里假设我们都知道KMP算法的基本原理,以及NEXT[]数组的定义。

于是有
<定义1>
对于一个模式串P[],有相应的NEXT[]。对于每个P[K+1]有NEXT[K+1]=X,此时
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’
因为,NEXT的意义在于使得模式串P[]与目标串T[]匹配到P[K-1]与T[J-1]都成功时,在P[K]!=T[J]的情况下,模式串需要移动后与目标串比较的位置。

以及
<结论1>
对于任意一个模式串P[]及其NEXT[],必然有
NEXT[1]=0;NEXT[2]=1
因为,第一个字符不匹配,只能将模式串右移,而第二个字符不匹配,只能比较第一个字符。

所以,现在根据以上得出的定义和结论,结合这样一个假设
<假设>
对于某个模式串P[]及其NEXT[],已知某个字符P[K]及其前面所有的NEXT[]对应的值。
基于结论1,显然成立。不妨设此时P[K]=Y;

现在,我们在上述假设下,求NEXT[K+1]=X,X为未知量。

那么根据<定义1>,显然有
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’
同时因为P[K]=Y,所以有
‘P[1]P[2]..P[Y-1]’ = ‘…P[K-1]’

实际上,由KMP的NEXT[]本身有“满足最大前后缀匹配”的原则(这个地方在理解上可以忽略,数学上也是可以证明的,本文就不证明了……),因此,

如果,P[Y]=P[NEXT[K]]=P[K],那么有
‘P[1]P[2]..P[Y-1]P[Y]’ = ‘…P[K-1]P[K]’
而上面已经提到
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’
“满足最大前后缀匹配”的性质,可以充要的推导出:
X-1=Y。
即当P[NEXT[K]]=P[K]时,NEXT[K+1]=NEXT[K]+1。

如果,P[Y]!=P[K],那么,设NEXT[Y]=Y2,(显然Y2 < Y),因为<性质1>
‘P[1]P[2]..P[Y2-1]’ = ‘…P[K-1]’
以及KMP的性质,则回到迭代求解的过程中。


由此就可以理解KMP算法中NEXT的求解了,希望能帮到更多人。
欢迎指正、讨论!

谢谢阅读!

你可能感兴趣的:(心得,算法入门)