假设有模式串 b c b c b e a
相对应有
next[0] = -1
next[1] = -1
next[2] = 0
next[3] = 1
next[4] = 2
next[5] = -1
模式串下标标号从0开始
当在下标i时发生不匹配,模式串下标回溯为next[i-1] + 1;
被匹配串下标不发生变化
需要注意的是,当寻找最长公共子串的下标范围为[0,i]时, 最长公共子串的前一串必须从0开始,后一串必须从i开始
代码如下,理解和解释附在注释里
next[0] = -1;//第一个字符不匹配回溯的下标仍然是这个下标
int k = -1;//(k+1)表示的是最长公共子串前一串的结尾下标
for(int i = 1; i < len; i++) {//下标为[0到i]的最长公共子串长度,
//这个长度记录在next[i]中
while(k != -1 && needle[k+1] != needle[i]) {
//为什么用while?
/*
后一串的最长公共子串的开始下标(前面提到的i这个点)改变,
可能会导致没有一个字母匹配,使k回到-1
*/
k = next[k];
//第k+1个字符不匹配时用next[k+1-1]回溯k值
//(如果是在和被匹配串匹配时这个式子还要+1,这个在上面提到过)
}
if(needle[k+1] == needle[i]) {
//最长公共前缀长度每次最多+1,
k++;
}
next[i] = k;
}
希望能帮到你!