上代码!!!
vector<int> GetNext(string str)
{
int index = 0; // 对str进行遍历时的索引
int k = -1; // next数组的值
vector<int> next(str.length(), 0); // 分配足够的空间并初始化
next[0] = -1; // 固定值
while(index < str.length() - 1)
{
if(k == -1 || str[k] == str[index])
{
++k;
++index;
next[index] = k;
}
else
k = next[k];
}
return next;
}
首先,我们要明白KMP算法的一些基本内容。
1、由于每一次最多增加一个字符,所以next[j+1]的最大值为next[j]+1。
2、重点:如果,那么next[j+1]可能的次大值为next[next[j]]+1,以此类推即可高效求出next[j+1]。
那么,我们来探索一下代码背后的原理,跟着代码走一遍
1.求next[j + 1],则一直next[1] 、next[2]......next[j](递归一下)
2.假如next[j] = k1,则(前k1 - 1位字符和后k1 - 1位字符是相等的)
3.如果,,则next[j + 1] = k1 + 1,否则进入下一步
4.假设next[k1] = k2,则有
5.由2、3,得:,即这四段相等。
6.若,则,即next[j + 1] = k2 + 1,否则重复4、5、6
图解上述过程:
假如k = 7,next[k] = 3. j = 15
我们可以看到,只需要对比str[7]和str[15]即可,若是相同的话则3成立,若不相同,那么
k = next[k] = 3
假设我们现在是这种情况,那么我们可以知道0--2 == 4--6
而0--7 == 8--14
所以4--6 == 12--14, 0--2 == 8--10
所以0--2 == 4--6 == 8--10 == 12--14
所以我们只需要对比 str[3]和str[15]地值,若是相同的话则3成立,不相同一直重复上述过程
理解了上面的原理,那么,求nextval数组的代码只需稍微修改一下即可
C++
vector<int> GetNextval(string str)
{
int index = 0; // 对str进行遍历时的索引
int k = -1; // next数组的值
vector<int> nextva;(str.length(), 0); // 分配足够的空间并初始化
nextval[0] = -1; // 固定值
while(index < str.length() - 1)
{
if(k == -1 || str[k] == str[index])
{
++k;
++index;
if(str[index] != str[k])
nextval[index] = k;
else
nextval[index] = nextval[k]
}
else
k = nextval[k];
}
return nextval;
}