package algorithm;
import java.util.Arrays;
public class KmpAPP {
public static void main(String[] args) {
// TODO 自动生成的方法存根
String str1="BBC ABCAB ABCDA";
String str2="ABCDA";
System.out.println("部分匹配表为:"+Arrays.toString(kmpNext(str2)));
int[] next=kmpNext(str2);
int index=kmpSearch(str1, str2, next);
if(index==-1) {
System.out.println("未有匹配字符串");
}else {
System.out.println("已匹配,首字母下标为:"+index);
}
}
//原字符串匹配比较字符串,若存在返回第一个字母下标,反之返回-1
public static int kmpSearch(String str1,String str2,int[] next) {
for(int i=0,j=0;i<str1.length();i++) {
if(j>0&&str1.charAt(i)!=str2.charAt(j)) {//如果此次字母匹配失败回溯j坐标
j=next[j-1];
}
if(str1.charAt(i)==str2.charAt(j)) {//如果相同后移比较字符串
j++;
}
if(j==str2.length()) {//此时已全部匹配到比较字符串
return i-j+1;//此时执行了j++但i++并未执行因此加一
}
}
return -1;
}
//获取该字符串的部分匹配值
public static int[] kmpNext(String dest) {
int[] next=new int[dest.length()];
next[0]=0;//字符串为单个字符时,部分匹配默认为0
for(int i=1,j=0;i<next.length;i++) {
if(j>0&&dest.charAt(i)!=dest.charAt(j)) {//若未匹配
j=next[j-1];
}
if(dest.charAt(i)==dest.charAt(j)) {//当匹配成功时,匹配表加一
j++;
}
next[i]=j;//给该段字符串相应匹配个数
}
return next;
}
}