因为找next值的时候是从第一个字符开始的,规定第一个字符的next值为0,即如果第一个字符的下标为0则next[0]=0,如果第一个字符的下标是1则next[1]=0。。。因为next值将作为主串的标,数组下标不能为负数,所以next[0]不能为-1。。。
先看看next数据值的求解方法。
位序 1 2 3 4 5 6 7 8。
模式串 a b a a b c a c。
next值 0 1 1 2 2 3 1 2。
next数组的求解方法是:
1.第一位的next值为0
2.第二位的next值为1
后面求解每一位的next值时,根据前一位进行比较。
3.第三位的next值:第二位的模式串为b ,对应的next值为1;将第二位的模式串b与第一位的模式串a进行比较,不相等;则第三位的next值为1。
4.第四位的next值:第三位的模式串为a ,对应的next值为1;将第三位的模式串a与第一位的模式串a进行比较,相同,则第四位的next值得为2。
5.第五位的next值:第四位的模式串为a,对应的next值为2;将第四位的模式串a与第二位的模式串b进行比较,不相等;第二位的b对应的next值为1,则将第四位的模式串a与第一位的模式串a进行比较,相同,则第五位的next的值为2。
6.第六位的next值:第五位的模式串为b,对应的next值为2;将第五位的模式串b与第二位的模式中b进行比较,相同,则第六位的next值为3。
7.第七位的next值:第六位的模式串为c,对应的next值为3;将第六位的模式串c与第三位的模式串a进行比较,不相等;第三位的a对应的next值为1,则将第六位的模式串c与第一位的模式串a进行比较,不相同,则第七位的next值为1。
8.第八位的next值:第七位的模式串为a,对应的next值为1;将第七位的模式串a与第一位的模式串a进行比较,相同,则第八位的next值为2。
以上这种分析方法,位序是从1开始的,如果位序从0开始,刚第一位的next值为-1,后面的方法则相同。
上代码,有详细说明
public class KMP {。
String model = "abcdabce";。
// String model = "abcabcabd";。
// String model = "aaaab";。
// String model = "asdaaaaaaabdabcabcaabaaaaaskdf";。
char[] tempModel = model.toCharArray();。
String str = "asdaaaaaaabdabcabcaabaaaaaskdf";。
char[] tempStr = str.toCharArray();。
int[] backto = new int[model.length()];。
int[] next = new int[model.length()];。
//查找用例
public void findStr(){。
int i=0;
int j=0;
while(i<tempStr.length){。
if(tempStr[i] == tempModel[j]){。
i++;
j++;
}else{
j = backto[j];。
if(j<0){。
i++;
j++;
}
}
if(j == tempModel.length){。
System.out.println(i+" "+tempStr[i-1]);。
j=0;
}
}
}
/**
* a a a a b。
* -1 -1 -1 -1 3。
*
* a b c d a b c e。
* -1 0 0 0 -1 0 0 3。
*/
public void next(){。
int i=0, //模式串下标,即当前位置.开始为0。
k=-1;//k表示字符串在位置i之前已匹配的子串最长长度.类似于模式串的下标(从0开始)。
next[i]=-1;//第一个next为-1。
while(i+1<tempModel.length){//i 模式串的当前位置,因为第一个next为-1,所以从第二个开始,往前查找模式长度。
if(k == -1 //初始,k,i直接自加:k=0,i=1。
|| tempModel[k] == tempModel[i]){//比较第k个字符和第i个字符。
i++;
k++;
if(tempModel[k] != tempModel[i]){//比较第k+1个字符和第i+1个字符不相等,说明k为当前模式最长长度.。
next[i] = k;//k最小为0,因为i是从第二个开始的。
}else{//第k+1个字符和第i+1个字符相等,说明第i+1个字符比较不同后,可后推到第next[k]个字符开始比较。
next[i] = next[k];。
}
}else{//往后找k值,此时k值表现为模式串的下标。
k = next[k];。
}
}
}
public void start(){。
System.out.println("--------------------------------");。
next();
//CommonUtil.printCharAndIntArray(tempModel,next);。
}
public static void main(String[] args){。
new KMP().start();。
}
应该滴结构体中的,是指I结构体或者是I指向的结构体中的next成员。是把next成员赋值为零。