1 原理
参考 《大话数据结构》第5章 串 的第5.7小节 : KMP模式匹配算法
2 java代码
KMP.java
package leaning.string.KMP;
public class KMP {
public static int indexKMP(String source, String target,int pos) {
/* i 用于主串source当前位置下标值,若pos不为1
则从pos位置开始匹配 */
int i = pos ;
/* j 用于子串 target中当前位置下标值 */
int j = 1 ;
/*定义一组next数组*/
int[] next = new int[IntArrayLength.length];
/*对target进行分析,得到next数组*/
next = NextUtil.getNext(target);
// 将source,target字符串变为字符数组
char[] sourceChar = KMPStringUtil.stringToChar(source);
char[] targetChar = KMPStringUtil.stringToChar(target);
//若i小于source长度并且target小于target长度,执行循环
while(i <=source.length() && j <= target.length() ){
if(j==0 || sourceChar[i] == targetChar[j] ){
++i;
++j;
}else{
j = next[j] ;
}
}
if( j > target.length() ){
return i - target.length();
}else{
return 0;
}
}
public static void main(String args[]) {
String source = "asdkfjslkfjwejdklfjew8odklfjsdlkfjslkdj";
String target = "w8odkl";
int pos = 0;
int p = KMP.indexKMP(source, target, pos);
System.out.println("在位置 " +p + "完全匹配");
}
}
NextUtil.java
package leaning.string.KMP;
public class NextUtil {
/**
*
* 得到next数组
* */
public static int[] getNext( String targetStr) {
if(targetStr==null) return null;
char[] targetModify = KMPStringUtil.stringToChar(targetStr); // 将targetStr字符串改为字符数组
int length = targetStr.length();
// 得到next数组
int i,j;
i = 1 ;
j = 0 ;
int next[] = new int[IntArrayLength.length];
while( i < length){
if(j == 0 || targetModify[i] == targetModify[j]){ // targetModify[i]表示后缀单个字符, targetModify[j]表示前缀的单个字符
++i;
++j;
next[i] = j ;
}else{
j = next[j]; // 若字符不同,则 j 进行回溯
}
}
return next;
}
public static void main(String args[]){
String targetStr = "ababaaaba" ;
int next[] = NextUtil.getNext(targetStr);
for(int i = 0 ; i < next.length ; i++){
System.out.print(next[i] + " ");
}
}
}
IntArrayLength.java
package leaning.string.KMP;
public class IntArrayLength {
public static int length = 255;
}
KMPStringUtil.java
package leaning.string.KMP;
public class KMPStringUtil {
public static char[] stringToChar(String source){
/**
* 对source进行改造,使其第一位为一个占位符
* source = a b c d e f g h
* targetModify = '' a b c d e f g h
*
* */
char[] targetModify = new char[source.length()+1];
int length = source.length() ;
for(int i = 0 ; i < source.length() ; i++){
targetModify[i+1] = source.charAt(i);
}
return targetModify;
}
}
3 运行结果
运行 KMP.java 得到下面结果