字串在内存中是不会一定的,是指针在移动,画图距离只是为了方便理解更加形象。
next[j]的含义:
当子串的第j个元素发生失配时,跳到子串的第next[j]位子重新与主串的当前位置进行比较。
(灰色部分代表上下字符相等)
next公式:
求Next 代码:
void get_next(SString T,int next[]){
int j=0;
int i=1;
next[1]=0;
while(i<T.length){
if(j==0||T.ch[i]==T.ch[j]){
i++,j++;
next[i]=j;
}else{
j=next[j];
}
}
}
求nextval数组(next的优化):
void get_nextval(SString S,int nextval[]){
int i=1;int j=0;
nextval[1]=0;
while(i<S.length){
if(j=0||S.ch[i]==S.ch[j]){
i++,j++;
if(S.ch[i]!=S.ch[j]){
nextval[i]=j;
}else{
nextval[i]=nextval[j];
}
}else{
j=nextval[j];
}
}
}
KMP匹配算法 代码:
int Index_KMP(SString S,SString T,int next[]){
int i=1;int j=1;
while(i<S.length&&j<T.length){
if(j==0||S.ch[i]==T.ch[j]){
i++;j++;
}
else{
j=next[j];
}
}
if(j>T.length){
return i-T.length;
}
else{
return 0;
}
}
时间复杂度:
普通匹配模式:O(mn)
KMP算法:O(m+n)
匹配方法的选取:
但在一般情况下普通匹配模式的执行时间近似O(m+n),所以至今仍被采用。KMP算法仅在主串与子串有很多“部分匹配”时才显得比普通算法快得多,其主要优点是主串不回溯。