有了(1)中的匹配思想,剩下的问题就是搞定next[i]了,其实也就是求字符串自匹配关系
t1t2…ti-1= tk-i+2tk-i+3…tk(i-1<k),i的最大值,直接用2个循环去求next[i]
当然可以,不过效率不好,特别是字符串t比较长的时候,假设ti满足字符串自
匹配的最大值为m,t1t2…tm= ti-mti-m+1…ti-1 ,next[i] = m+1或者m不存在时
next[i] = 0(i>2),next[0]一般表示为-1,next[1] = 0。我们来看next[i+1]和next[i]的关系,
如果tm+1=ti,显然有next[i+1] = next[i]+1, 否则如果tm+1≠ti,这是第m+1个字符失配
的情况,记j=next[m+1],下次需要比较ti和tj,如果失配j=next[j],继续比较,
直到j==-1或者匹配为止
字符串t="abababaac"的next值如下表:
|
a |
b |
a |
b |
a |
b |
a |
a |
c |
i |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
next[i] |
-1 |
0 |
0 |
1 |
2 |
3 |
4 |
5 |
1 |
next[i]代码如下
next[0] = -1;
next[1] = 0;
for (i=2; i<tlen; i++){
j = next[i-1];
if(t[i-1] == t[j])
next[i] = next[i-1] + 1;
else{
while(j!=0 && t[i-1] != t[next[j]])
j = next[j];
next[i] = next[j]+1;
}
}
还有种教科书上常用的写法,直接进行比较求next[i],更加简洁
next[0] = -1;
next[1] = 0;
i=1, j=0;
while (i<tlen){
if (j == -1 || t[i] == t[j]){
++i;
++j;
next[i] = j;
}
else
j = next[j];
}