小弟昨天看了一下午串的匹配,可是仍是看不懂kmp的思想,对kmp知其然但不知其所以然,只好练此葵花宝典,以求速成。
注意j,k都为下标, 我不会输入,所以只能表现为pj,pk这种形式。
KMP中最关键的便是求next[j]的值,(next[j]的值之与他的模式串有关,就是说只要知道模式串就能知道next[j]的值),在书上next[j]的值总共有3种情况(j从1开始的):1,当j==1时,next[j]=0 .
2,当j==2或者pj之前没有匹配部分,next[j]等于1。
第3种,也是最重要的情况,max{k|k<j且“p1.....p(k-1)”=“p(j-k+1)....p(j-1)”}
废话不多说,看个例子:
这个模式串:a,b,a,b,a,c
它的next[j]求法: j=1时,显然由公式知next[j]=0,满足第一种情况
j=2时,next[j]=1,满足第2种情况
j=3时,当k=2时,p1!=p2 (第一个a不等于第1个b) ,满足第2种情况
j=4时,当k=2时,p1!=p3,当k=3时,p1p2!=p2p3(即ab!=ba),满足第2种情况
...按此来,求完,即可得出next[j]的值。
上面是速成方法,下面是写代码的算法。
求next[j]的算法如下
1:next[1]=0
2:next[j]=k,1<k<j,且满足“p1.....p(k-1)”=“p(j-k+1)....p(j-1)”
在2的情况下,1:若pk=pj,则next[j+1]=k+1=next[j+1]。(注意,k值即为next[j]的值)
2:pk!=pj,用pnext[k]与pj比较,若pnext[k]=pj,则则next[j+1]=next[k]+1若不等于,继续重复在2情况下的2,直到相等或满足初始条件next[1]=0(此处我不懂,这是不懂原理惹的祸)。
kmp匹配的原理,已经比较到主串的第i个字符和模式串的第j个字符,若不等,next[j]赋给j,继续与此时的下标i所对应的字符比较。