部分难点的一些理解
求next值的代码
Void get_next(string st,int next[])
{
int i=1;j=0;
next[1]=0;
for(i=1;i<st.length();)
{
if(j==0||st[i]==st[j])
{
i++;j++;
next[i]=j;
}
else j = next[j];//重难点,next数组代码实现理解的关键
}
}
算法实现思想
默认初始值next[1]=0,next[2]=1;
遍历i和j,如果相等就说明从1 到 j和从 i-j 到 i 的数是相同的,因此最长的相等前后缀长度就为j。如果不相同,就要执行j=next[j]来去找小一点的最长相等前后缀长度。(这一点下面会详细讲解)
下标i和j
首先i和j是用来遍历st的,但重要的是i 代表着后缀末尾,j代表的是前缀末尾。
为什么使用j=Next[j]就可以找到小一点的最长相等前后缀长度
假设现在有字符串st。
已知从1-6和12-18的字符串是一样的,因此此时最长相等前后缀长度为6。(2个区间内任意长度的字符串都相同)
即next[19]=6+1
此时若st[19]!=st[7],我们就需要去寻找更小的最长相等前后缀长度。
而next[j]即next[7]代表的就是前6个字符串的最长相等前后缀长度,也就是存在一个最大的k, 使1 到k 的字符串和 6-k + 1到6 的字符串相等。此时,这个6-k+1到 6这个区间在 12-18也有一个完全相同的字符串。此时最大的相等前后缀长度为k。
这就是为什么使用j=next[j]就可以找到小一点的最长相等前后缀长度。