一、代码实现
int Index_KMP(SString s,sstring T,int next[] ){
int i=1, 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;
}
二、next数组手算方法
注意:next数组的第一个数只能是0,第二个数只能是1。
例1:模式串为 a,b,a,b,a,a
1.当第3个数不匹配时
我们可知主串的前两个为a,b,其他未知
将模拟串后移,直到遇到可以匹配的字符串,或问号后停止,j指向1
2.当第4个数不匹配时
3.当第5个数不匹配时
4.当第6个数不匹配时
三、nextval数组求法
1.代码实现
nextval[1]=0;
for (int j=2;j<=T.length;j++){
if(T.ch[next[j]]==T.ch[j])
nextval[j]=nextval[next[j]];
else
nextval[j]=next[j];
}
2.例子
(1)我们先得到一个模拟串的next数组,设定一个nextval数组,nextval[1]一定为0。
(2)从第2个开始判断,此时,j==2,next[j]==1, string[j]==b,
我们使用next[j]作为新的j1,也就是j1==1,string[j1]==a。
因为两次得到的字符一个为a一个为b,不相等,所以nextval[j]等于next[j].
(3)判断第3个,此时,j==3,next[j]==1, string[j]==a,
我们使用next[j]作为新的j1,也就是j1==1,string[j1]==a。
因为两次得到的字符都是a,相等,所以nextval[j]等于nextval[ next[j] ]。
(4)判断第4个,此时,j==4,next[j]==2, string[j]==b,
我们使用next[j]作为新的j1,也就是j1==2,string[j1]==b。
因为两次得到的字符都是b,相等,所以nextval[j]等于nextval[ next[j] ]。
(5)判断第5个,此时,j==5,next[j]==3, string[j]==a,
我们使用next[j]作为新的j1,也就是j1==3,string[j1]==a。
因为两次得到的字符都是a,相等,所以nextval[j]等于nextval[ next[j] ]。
(6)判断第6个,此时,j==6,next[j]==4, string[j]==a,
我们使用next[j]作为新的j1,也就是j1==4,string[j1]==b。
因为两次得到的字符一个是a一个是b,不相等,所以nextval[j]等于next[j]。
(7)得到最终的优化数组为
优点:可以减少时间复杂度