KMP算法的详解

主要是看了左程云老师的算法书 对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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值