Next数组计算
Next数组用于存储回溯时的位置
前缀集合 是指当前串从前之后的前缀的集合,不包含当前串(不包含当前串的最后一个字符)
后缀集合 是指当前串从后至前的后缀的集合,不包含当前串(不包含当前串的第一个字符)
所以next[6]=0,同理next[5]=3
当匹配成功时,则前后缀相同数(回溯下标)加一,当前串长度也增加一;
当匹配至next[5]失败时,不需要回溯至next[0],只需要回溯至next[next[j]]即next[k=3]处开始匹配,因为k为回溯下标,所以k=next[k],而主串的下标则不需要回溯
static void getNext(String str, int[] next) {
int j = 0, k = -1;//j表示为当前串的最大下标,k表示后缀与前缀相同最大数,可从next[k]处开始匹配
next[0] = -1;
while (j < str.length() - 1) {
if (k == -1 || str.charAt(j) == str.charAt(k)) {//j遍历后缀,k遍历前缀
j++;
k++;
next[j] = k;
} else {
k = next[k];
}
}
}
KMP部分代码
static int kmp(String str1, String str2) {
int[] next=new int[str2.length()];
int i=0,j=0;
getNext(str2,next);
while(i<str1.length()&&j<str2.length()){
if(j==-1||str1.charAt(i)==str2.charAt(j)){
i++;j++;
}else{
j=next[j];
}
}
if(j>=str2.length()){
return (i-str2.length());//匹配成功,返回模式串结果开始处的下标
}else{
return -1;
}
}