上一篇记录了一些理论,现在研究一下代码,KMP算法比较重要的是next函数,代码如下
public static int[] matchTable(String str) {
char[] p=str.toCharArray();
int pLen = p.length;
int[] next = new int[pLen];
int k = -1;
int j = 0;
next[0] = -1; // next数组中next[0]为-1
while (j < pLen - 1) {
if (k == -1 || p[j] == p[k]) {
k++;
j++;
next[j] = k;
} else {
k = next[k];
}
}
return next;
}
next函数是求str的每一个字节的最大模式字串,数组的下标对应字符串的索引,数组的值对应上一个索引对应的str最大模式字串的长度
next[0]=-1:因为next数组的索引对应字符串的索引,而且当前索引对应上一个索引的最大长度,所以当i=0时,不存在上一个索引,固令next[0]=-1
分析代码:令str=“issip” j代表str的索引 k表示最大模式字串的下标
1.当j=0时,k=-1,走if分支,k=0,j=1,num[1]=0
2.当j=1时,k=0,此时p[1]=s p[0]=i,不相等,else 分支,j不变,k=-1
3.当j=1时,k=-1,走if分支,k=0,j=2,num[2]=0
4.当j=2时,k=0,此时p[2]=s p[0]=i,不相等,else 分支,j不变,k=-1
5.当j=2时,k=-1,走if分支,k=0,j=3,num[3]=0
6.当j=3时,k=0,此时p[3]=i p[0]=i,相等,if分支,k=1,j=4,num[4]=1
7.当j=4时,k=1,此时p[4]=p p[0]=i,不相等,else 分支,j不变,k=-1
public int strStr(String haystack, String needle) {
if(null==haystack || null==needle){
return -1;
}
if(0==needle.trim().length()){
return 0;
}
if(0==haystack.trim().length()){
return -1;
}
int i=0,j=0;
int next[]=matchTable(needle);
while(i<haystack.length() && j<needle.length()){
if(j==-1 || haystack.charAt(i)==needle.charAt(j) ){
i++;
j++;
}else{
j=next[j];
}
}
if(j==needle.length()){
return i-j;
}
return -1;
}
j=next[j];这一块就相当于一个小的递归
假设当j=3时,判断失败,else分支,j=next[3]=当k=2时的索引
如果此时j!=-1 并且不想等,else 分支,j=next[2]=当k=1时的索引
.。。。
依此类推