kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是根据给定的模式串W1,m,定义一个next函数。next函数包含了模式串本身局部匹配的信息。
/**
* KMP算法
* @author 过路的守望
*
*/
public class KmpAlgorithm {
public static void main(String[] args) {
String A = "jahellockHelloHelloJJJJ";
String B = "HelloHello";
System.out.println(new KmpAlgorithm().getSubIndex(A, B));
}
/**
* 目标串与模式串匹配
* @param A
* @param B
* @return
*/
public String getSubIndex(String A,String B){
int[] next = getNext(B);
int k = 0;
int len = A.length();
int b_len = B.length();
int endIndx = 0;
for(int i = 0;i<len;i++){
while(k>0&&A.charAt(i)!=B.charAt(k)){
k = next[k-1];
}
if(A.charAt(i) == B.charAt(k)){
k++;
}
if(k == b_len ){
endIndx = i;
break;
}
}
return A.substring(endIndx-k+1,endIndx+1);
}
/**
* 模式串自身匹配
* @param B
* @return
*/
public int[] getNext(String B){
int len = B.length();
int[] next = new int[len];
/*
* S[0,k-1]=S[i-k,i-1]
* 字符串0到k-1的字符与i-k到i-1的字符匹配。
* 现在比较下标k和i的字符是否匹配,若匹配则比较两者的下一个字符。
* 若不匹配则回溯k=next[k-1]是新的k满足S[0,k-1]=S[i-k,i-1]再次匹配。
*/
int k = 0;
next[0] = 0;
for(int i = 1;i<len;i++ ){
while(k>0&&B.charAt(k) != B.charAt(i)){
k = next[k-1];
}
if(B.charAt(k)==B.charAt(i)){
k++;
}
next[i] = k;
}
return next;
}
}
图片引用: