网上已经有很多示例的 但是感觉关键点并没有合适的注释 ; 于是自己写了一版; 记录一下
import java.util.Arrays;
/**
* @author chonggao
* @date 2018/5/28
**/
public class Kmp {
/**
* 生成 查询失败回退的数组
* @param pattern
* @return
*/
private int[] mp(String pattern) {
int[] res = new int[pattern.length()];
int j = 0;
for (int i = 1; i < pattern.length(); i++) {
while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) {
// 如果连续中断 则从后往前找合适的标记位置
j = res[j];
}
if (pattern.charAt(i) == pattern.charAt(j)) {
j++;
}
res[i] = j;
}
System.out.println(Arrays.toString(res));
return res;
}
/**
* 查询方法
* @param content
* @param pattern
* @return
*/
public int kmp(String content, String pattern) {
assert content != null && pattern != null;
int i = 0;
int j = 0;
int cLen = content.length();
int pLen = pattern.length();
int[] next = mp(pattern);
int res = 0;
while (true) {
if (j == pLen) {
//找到结果
return res;
}
if (i >= cLen) {
//没找到
return -1;
}
if (content.charAt(i) == pattern.charAt(j)) {
i++;
j++;
} else {
//i 不动 j移动到合适的位置
j = next[j];
if (j == 0) {
i++;
res = i;
}
}
}
}
public static void main(String[] args) {
Kmp kmp = new Kmp();
String ss = "abcdefabcdefabcdefabcdefvabv";
System.out.println(kmp.kmp(ss, "va"));
}
}