KPM算法简介:
A B C A B C D J B N K (文本串)
A B C A B B (模式串)
例如这个文本串与模式串,前5个元素都匹配,直到第六个元素不匹配,按照暴力算法,应该将模式串向后移动一个单位,在依次比较,而KMP算法的做法是:
A B C A B C D J B N K
A B C A B B
KPM算法分析:
当文本串与模式串比对的时候,如果在某个位置比对终止,此时有 T[i]!=P[j] ,那么要设法保持文本串指针不回溯,只移动模式串的指针,现在关键就是计算模式串移动几个单位。
前一轮比对中,确定的文本串与模式串的匹配范围是:
P[0,j]=T[i-j,i]
那么如果模式串P经过右移之后,能够与T的某一子串完全匹配的必要条件是:
P[0,t)=P[j-t,j)=T[i-t,i)
也就是说,在P[0,j]中长度为t的真前缀,必须要与产长度为t的真后缀完全匹配,则 t 来自计集合:
N(P, j) = {0<= t < j | P[0,t) = P[j-t,j) }
那么下一轮比对将从T[i]与P[t]开始,相当于将P右移 j-t 个单位。同时t的值应该在集合N(P, j)中挑选最大的。
令:next[ j ] = max ( N( P, j ) )
KPM主算法:
int match(char *P,char *T){
int *next=buildNext(P);
int n=(int)strlen(T);
int i=0;//文本串指针
int m=(int)strlen(P);
int j=0;//模式串指针
while(j<m&&i<n){
if(0>j||T[i]==P[j]){
i++;
j++;
}
else
j=next[j];//模式串指针右移,保持文本串指针不回溯
}
delete []next;
return i-j;
}
构造模式串P的next表的算法: