目录
KMP算法计算next值和nextVal值
给定一个主串S及一个模式串P,判断模式串是否为主串的子串;若是,返回匹配的第一个元素的位置(序号从1开始),否则返回0;
这里先不写算法,仅仅计算next和nextVal值
那么计算时只用到子串,也就是模式串
这里模式串为:abaabcac
第一步将模式串写上序号,我们这里从1开始(有的从0开始,写代码推荐从 0开始,少一些操作)
maxL
列出从第一个开始的子串,找出相等的前缀和后缀的个数
maxL 计算过程
maxL[i] = k 表示,以 i位置结尾的 最长前后缀 长度。
一般来说 : j 是前缀的结尾, i 是后缀的结尾。
前缀 = = 后缀, 且前缀 长度要 小于 (严格小于 1~i-1)
注意 : 以下 图中 next 应为 maxL
0.初始化
下标从 1 开始, maxL[1] = 0; j = 1, i = 2;
1.str[i] == str[j]
若 str[i] == str[j] , 则maxL[i] = j; j++; i++ ;
maxL[i] = j 的解释 : 由于maxL保存的以i位置结尾的最长前后缀 长度。 当str[i] == str[j] 时。
i 指向后缀的最后一个, j 指向前缀的的最后一个。由于下标从 1 开始。
所以 j 就是前缀的长度。恰好应该赋值给maxL[i]
2.str[i] != str[j]
1. j 可以回退(j > 1)
2.j == 1, j 不能回退。则 maxL[i] = 0, 必然为 0.
解释: 当 str[i] == str[j] 时, j.i是 增长的 最大前后缀 的 末尾元素。
但是当 str[i] != str[j] 时, j,i 分别是 最大前后缀 的末尾元素 的 再后一个元素。
由于此时 j == 1 .j之前必然没有前缀了。所以maxL[i] = 0; 表示 没有 以 i 结尾的 后缀。
代码
public void getmaxL(String subStr, int[] maxL){
// 下标从 1开始。
subStr = " "+subStr; // 第 0 位 为 ' ' 空格
int j = 1, i = 2;
maxL[1] = 0;
while(i < maxL.length){
// 每轮开始, i ,j 一定指向最大前后缀最后一个元素的 后 一个
if(subStr.charAt(j) == subStr.charAt(i)){
maxL[i] = j; // j == maxL[i-1] + 1; 当 连续递增时。
i