KMP算法(算NXET表)
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特–莫里斯–普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。
NEXT[ ] 表
而在KMP算法中,对于每一个模式串我们会事先计算出模式串的内部匹配信息,在匹配失败时最大的移动模式串,以减少匹配次数。
例如
给定一个模式串T[6]={a,b,a,b,a,c}
j | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
T [ ] | a | b | a | b | a | c |
next [ ] | -1 |
我们设两个参数 j,k
令 j = 0, k = -1并且next[0]=-1(就是算法规定,不要问为什么这样设)
while(j < 模式串长度-1)//为啥不是j<模式串长度呢,其实我们算next[5]时,j=4,如果匹配了j++, 不就算出来next[5]了嘛。
if(k==-1 || T[j]==T[k])
{
k++;
j++;
next[j] = k;
}
else k = next[k];
带大家算一遍
j=0, k=-1;符合 k==-1, 所以 j++,k++(此时 j=1,k=0) next[j] = 0;
j=1, k=0;T[j] !=T[k], 所以 k = next[k]=next[0]=-1 并且 j 的值不变(这一遍我们并没有算出 next[3]的值别担心继续往下算。)
j=1, k=-1;符合 k==-1, 所以 j++,k++(此时 j=2,k=0) next[j] = k =0;
j=2, k=0;T[j]=T[k],所以 j++,k++(此时j=3,k=1)next[j]= k =1;
j=3, k=1;T[j]=T[k],所以 j++,k++(此时j=4,k=2)next[j]= k =2;
j=4, k=2;T[j]=T[k],所以 j++,k++(此时j=5,k=3)next[j]= k =3;
j=5 = 模式串长度-1,循环结束。next表也求了出来。
j | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
T [ ] | a | b | a | b | a | c |
next [ ] | -1 | 0 | 0 | 1 | 2 | 3 |