推导
KMP是一种字符串模式匹配的改进算法。假定模式串为B,主串为A,当B[j]和A[i]不匹配时,i不会回退,j并不会从位置0开始重新匹配,而是回退到合适的位置。那么,KMP算法首先应该解决的就是如何找到合适的回退位置。
代码
显然时间复杂度为O(n + m), 空间复杂度为O(m),n是文本串的长度,m是模板串的长度
/**
* kmp算法
*
* 计算模板串S在文本串T中出现了多少次
* @param S string字符串 模板串
* @param T string字符串 文本串
* @return int整型
*/
public int kmp (String S, String T) {
// write code here
char[] sChars = S.toCharArray();
char[] tChars = T.toCharArray();
int i = 0, j = 0;
int sLen = sChars.length, tLen = tChars.length;
int res = 0;
int[] next = getNext(sChars);
while (j < sLen && i < tLen) {
if (j == -1 || sChars[j] == tChars[i]) {
++i; ++j;
if (j >= sLen) {
j = next[j];
res++;
}
} else
j = next[j];
}
return res;
}
/**
* 获取KMP的next数组
* @param s
* @return
*/
private int[] getNext(char[] s) {
int len = s.length;
int[] next = new int[len + 1];
next[0] = -1; // 表示右移被匹配字符串(文本串)的指针
int i = 0, j = -1;
while (i < len) {
if (j == -1 || s[i] == s[j]){
++i;
++j;
if (i < len && j < len && s[i] == s[j])
next[i] = next[j];
else
next[i] = j;
}
else
j = next[j];
}
return next;
}