主要是看了左程云老师的算法书 对kmp算法有了更深的领悟
注意:左老师对next[]数组(他书中的是nextarr[]数组)的含义的定义与以往数据结构书上的定义含义不同 但是非常好理解。
贴上连接:http://blog.csdn.net/u010485491/article/details/52032322 这个博主也是左派 讲的非常详细;值得参考。
最后贴上自己的代码:
package zuotext;
public class KMPtext {
public static void main(String[] args) {
String a = "aaaaaaaaaaaaaaaaab";
String b = "aaaab";
int index = getIndexOf(a, b);
System.out.println(index);
}
public static int getIndexOf(String s,String m) {
if(s==null || m==null || m.length()<1 || s.length()<m.length()) {
return -1;
}
char[] ss = s.toCharArray();
char[] ms = m.toCharArray();
int si = 0;//记录str的遍历
int mi = 0;//记录match的遍历
int[] next = getNextArray(ms);//match的next数组
while(si<ss.length && mi<ms.length) {//直到两个都字符串都到头 结束
if(ss[si]==ms[mi]) {//如果str和match遍历到i时的字符串相等 则都加一 往后继续遍历
si++;
mi++;
}else if(next[mi] == -1) {//当遍历到i 两个串的字符串不相等 且 next为-1 即match从match[0]开始比较
//这种情况是 两个都是刚开始从第一个比较 即第一个字符就不同 然后 str向后移动一个
si++;
}else {//当遍历到i字符串不同 且不在第一字符上时
mi = next[mi]; //match就从match[i-1]最大匹配值后的值开始比较 正好是next数组计算出的值
}
}
return mi==ms.length?si-mi:-1;//返回的是 如果mi和ms的长度相等 即match全部匹配成功
//返回str的最终停止的点 减去match的长度 就是匹配开始的点
//不然就是没匹配成功 返回-1
}
public static int[] getNextArray(char[] ms) {
//传进去的模式串字符数组
if(ms.length == 1) {
return new int[] {-1};
}
int[] next = new int[ms.length];
next[0]=-1;
next[1]=0;
int pos = 2;//从ms[2]开始 当前遍历到值
int cn=0;//跳转的变量
while(pos<next.length) {
if(ms[pos-1]==ms[cn]) {
next[pos++]= ++cn;//将cn赋值给点前位置的next数组 然后再自加
}else if(cn>0){
cn=next[cn];
}else {
next[pos++]=0;
}
}
return next;
}
}
其时间复杂度为:O(N);