字符串KMP匹配
①暴力匹配法
②next数组
③求next数组
//暴力法
static int indexOf(String s1,String s2){
int i = 0;
int l = i;
int j = 0;
while(i < s1.Length()){
if(s1.charAt(l) == s2.charAt(j)){
l++;
j++;
if(j == s2.Length()){
return i;
}
}else{
i++;
l = i;
j = 0;
}
}
}
i++
j每次从0开始
KMP匹配
KMP匹配i不回溯,j回溯一部分
①Pi == Pj -> i++,j++;
②Pi != Pj -> j回溯到next[j]
static int KMP(String s1,String s2){
if(s2.Length() < 1){
return -1;
}
int s1Len = s1.Length();
int s2Len = s2.Length();
//先不管next怎么求出来的
int[] next = Next(s2);
int i = 0;
int j = 0;
while(i < s1Len){
//j<0的时候肯定是第一个数失配0,-1
//i++,j++变成1,0
//跳过第一个失配的元素,接着对比后面的
if(j < 0 || s1.charAt(i) == s2.charAt(j)){
i++;
j++;
if(j == s2Len){
return i - s2Len;
}
}
else{
j = next[j];
}
}
}
求next数组
static int[] Next(String ps){
int len = ps.Length();
int[] next = new int[len];
next[0] = -1;
if(len < 2){
return next;
}
next[1] = 0;
//因为要算1+1的值
//初始化j=1,k=next[j];
int j = 1;
int k = next[j];
//因为是通过上一个下标算下一个小标
//到不了最后一个,倒数第二个执行一下就可以了
while(j<Len-1){
if(k < 0 || ps.charAt(j) == ps.charAt(k)){
next[++j] = ++k;
}else{
k = next[k];
}
}
}