void Getnext(int next[],String t)
{
//k表前缀,j表后缀。
//随着一次次的匹配成功,后缀的长度越来越长,1->length
//前缀也是随着一次次匹配成功长度慢慢加长1,2,3..
//前缀总是短的,类似一些小片段,一旦匹配不成功,咔嚓,当前的前缀片段就得换成别的片段重新匹配
//换成哪个前缀片段?next[]里面的值指定了指针跳转的位置,因为每次匹配成功,next[]都记录了片段的长度,也即尾部指针。
int j=0,k=-1;
next[0]=-1;
while(j<t.length-1) //j=0,1,2,3...
{
if(k == -1 || t[j] == t[k]) //前缀字串=后缀字串
{
//当 t[j] == t[k] 时,必然有"t[0]…t[k-1]" == " t[j-k]…t[j-1]"
//k代表前缀字串与后缀字串中有k个首字符连续匹配
//此时的 k 即是相同子串的长度。
j++;k++; //前缀字串指针右移,后缀字串指针右移
if (t[j] == t[k]) { // 当两个字符相等时要跳过,j++指向当前后缀字符+1,k++指向前缀字串+1
next[j] = next[k]; //上级回溯指针赋给本级回溯指针
} else {
next[j] = k; //next[]存放子串长度
}
}
else k = next[k]; //回溯,当模式匹配串失配时,next数组对应的元素指导应该用T串的哪个元素作为前缀进行下一轮的匹配
}
}
int KMP(String s,String t)
{
//s表示目标串,t表示模式串
int next[MaxSize],si=0;ti=0;
Getnext(t,next);
while(si<s.length&&ti<t.length)
{
if(ti==-1 || s[si]==t[ti]) //
{
si++;
ti++;
}
else ti=next[ti]; //失配,回溯模式串指针,避免了模式串开头几个字符的重复匹配
//利用已经部分匹配这个有效信息,保持i指针不回溯,通过修改j指针,让模式串尽量地移动到有效的位置
}
if(ti>=t.length)
return (si-t.length); //匹配成功,返回子串的位置
else
return (-1); //没找到
}
KMP算法--笔记
猜你喜欢
转载自blog.csdn.net/mynameisJW/article/details/104315839
今日推荐
周排行