时间复杂度:o(m+n)
需求:解决字符串是否包含字符字串的问题;
思路:定义一个主串的指针i 字串的指针j 当i和j下标的字符相同,i++;j++; 当不同时,从j=0开始找以j-1下标字符结尾的字符真子串,其长度为len, 与j-1下标开始回退len长度的字符真子串进行比较,如相同j=len; 那么我们有必要设置字串的next[] 数组保存当前元素如果与主串不同时,len的长度也就是下次j位置;
public class KMP{
public static int[] getNext(String sub,int [] next){
next[0]=-1; //一开始就匹配失败;
next[1]=0;//这两个都是固定的;
int k=0; //前一项的k;
int j=2;
while( j<sub.length() ){
if(k==-1 || sub.char(j-1)==sub.char(k)) {
//要想知道j不相等时的k;那么必须知道前一项(j-1)的k和j-1下标的值是不是相等;
//k=-1时, 说明j需要回退到j=1,借用循环使它变为0;
next[j]=k+1;
k++;
j++;
} else{
k=next[k];
}
}
}
public static int kmp(String str,String sub,int index){
int i=index;
int j=0;
int [] next=new int [sub.length()];
next= getNext(sub,next);
while(i<str.length && j<sub.length){
if(j==-1 || str.charAt(i)==str.charAt(j)){ //j=-1 说明j=0的时候就匹配失败,那么就应该从i++进行匹配,j++为了j=0;
i++;
j++;
}else{
j=next[j]; //j需要回退
}
}
if(j>=sub.length){
return i-j ;
}
return -1;
}
public static void main(String [] args){
String str="ababcabcdabccde";
String sub="abcd";
System.out.println(kmp(str,sub,6));
}
}