1. KMP算法原理
KMP算法的原理,请参考下面这篇博客,讲解的比较浅显易懂,也算透彻。
http://www.cnblogs.com/c-cloud/p/3224788.html
2. KMP算法实现
java实现:
public class KMP {
public static void main(String[] args) {
String parentString = "abaabfdfcabdfdfa";
String pattern = "cab";
int[] result = computeOverlay(pattern);
kmp(parentString, pattern, result);
}
/**
* 覆盖函数,用于计算匹配字符串的每个字符的部分匹配值,从0开始计数。
* @param pattern [description]
* @return [description]
*/
public static int[] computeOverlay(String pattern) {
int len = pattern.length();
int[] overlay = new int[len];
overlay[0] = -1;
for(int i = 1; i < len; ++i) {
int index = overlay[i - 1];
System.out.println("i=" + i + " index=" + index);
if(index >= 0 && pattern.charAt(i) != pattern.charAt(index + 1)) {
index = overlay[index];
}
if(pattern.charAt(i) == pattern.charAt(index + 1)) {
overlay[i] = index + 1;
} else {
overlay[i] = -1;
}
}
return overlay;
}
/**
* kmp匹配函数
*/
public static void kmp(String parentString, String pattern, int[] overlay) {
// 匹配字符串的游标
int patternIndex = 0;
// 父串游标
int targetIndex = 0;
while(targetIndex < parentString.length() && patternIndex < pattern.length()) {
if(parentString.charAt(targetIndex) == pattern.charAt(patternIndex)) {
// 继续匹配后一个字符
targetIndex++;
patternIndex++;
} else if (patternIndex == 0) {
// 从父串后一个字符开始重新匹配
targetIndex++;
} else {
/**
* 核心步骤:
* 首先,targetIndex并没有移动,而是保持在第一次不匹配的字符处
* patternIndex根据部分匹配值来进行匹配,因为部分匹配值反映了已匹配的部分是否还需重新开始匹配
* 因为overlay数组从0开始计数,所以取出数组的数要加1
*/
patternIndex = overlay[patternIndex - 1] + 1;
}
if (patternIndex == pattern.length()) {
System.out.println("Have found ! " + (targetIndex - pattern.length()));
return;
}
}
System.out.println("Not found !");
return;
}
}
只是简单实现算法,并没有做一些优化。
(真是醉了!!!代码格式粘上去就乱了!!!)