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 c 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.