KMP算法太好忘了,记录一下
public int kmp(char[] s, char[] p) {
if (s == null || p == null || p.length == 0 || s.length < p.length) return -1;
// next数组用于当s与p的字符不匹配时,不用将指针i前移,而是将p整体后移
// 即当当前元素不匹配时,应去匹配哪个元素
int[] next = getNext(p);
int i = 0, j = 0;
while (i < s.length && j < p.length)
if (j == -1 || s[i] == p[j]) {
i++;
j++;
} else
j = next[j];
return j == p.length ? i - j : -1;
}
// ABCDABD[-1, 0, 0, 0, 0, 1, 2]
// 本质求前缀和后缀匹配长度
private int[] getNext(char[] s) {
int[] next = new int[s.length];
// i表示前缀起点,j表示后缀终点
int i = -1, j = 0;
next[j] = i;
while (j < next.length - 1) {
if (i == -1 || s[i] == s[j]) {
i++;
j++;
next[j] = i;
} else
i = next[i];
}
return next;
}
两个很好理解的博客:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html