思想:
1.每次移动next【】数组里面保存的前缀和后缀所含有的子字符
2.利用回溯
public static int kmpsearch(char str[],char ptr[]){
int []next=cal_next(ptr);
int k=-1;
for (int i = 0; i < str.length; i++) {
while(k>-1&&ptr[k+1]!=str[i]){
k=next[k];
}
if(ptr[k+1]==str[i]) k++;
if(k==ptr.length-1){
return i-ptr.length+1;
}
}
return -1;
}
//获取next数组
public static int[] cal_next(char data[]) {
int k = -1;
int next[] = new int[data.length];
//-1
next[0] = -1;
//k是-1开始所以要length-1,并且i要从1开始
for (int i = 1; i < data.length - 1; i++) {
while (k > -1 && data[k + 1] != data[i]) {//只要data【k】!=data【i】就要回溯 ,前提是k大于-1
k = next[k];//回溯前一个
}
if (data[k + 1] == data[i])
k++;//
next[i] = k;
}
return next;
}