KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如
LeetCode的shortest Palindrome 就是基于KMP算法求最短子字符串。
public static int[] longestPS(String s) {
int sLen = s.length();
char[] p = s.toCharArray();
//存放最大前缀后缀数
int[] lNext = new int[sLen];
//最大前后缀数(前缀指针)
int k = 0;
//后缀指针
int j = 1;
while(j < sLen) {
if(p[k] == p[j]) {
//相等则将前一次比较的结果加上这次:k+1;然后继续加1比较。
lNext[j] = k + 1;
k++; j++;
} else {
//如果p[k] != p[j]则k是不是在初始位置,是的话,K不变,后缀指针加1;
if(k == 0) {
j++;
} else {
//k不为0,说明指针不在初始位置。根据lNext数组,找到上一个最大前后缀数的位置,继续判断。
k = lNext[k-1];
}
}
}
return lNext;
}
/*
* 举例:字符串 ABDABCE
* 对应的lNext == {0,0,0,1,2,0,0};
*
*/
下面是KMP的next数组代码,用以比较。
public void GetNext(char* p,int next[]) {
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1) {
if (k == -1 || p[j] == p[k]) {
++k;
++j;
next[j] = k;
} else {
k = next[k];
}
}
}
如果想要更详细的学习KMP算法,建议请移步此篇博客,
从头到尾彻底理解KMP,这是我学习中收收获最多的。