kmp算法

public class kmp {
    /**
     * 主函数:返回 str2 在 str1 中第一次出现的位置
     * @param str1 :母串
     * @param str2 :标准串
     * @return str2 在 str1 中第一次出现的位置
     */
    public static int getIndexOf(String str1, String str2){
        if (str1==null||str2==null||str1.length()<1||str2.length()<1)return -1;
        char[] s1 = str1.toCharArray();
        char[] s2 = str2.toCharArray();
        int[] next = getNext(s2);
        int p1=0;  //长数组的指针,纪录长数组的位置
        int p2=0; //同上,短
        while (p1<s1.length&&p2<s2.length){
            if (s1[p1]==s2[p2]){   //如果相等,两个字符组同时向后移动
                p1++;
                p2++;

            }else {
                if (next[p2]>0){
                    p2=next[p2];
                }else {
                    p1++;
                }
            }

        }
        //如果p2越界---》成功,p1是长的数组当前位置,p2是短的数组的长度,p1-p2是长的数组遇见短数组的初始位置
        return p2==str2.length()?p1-p2:-1;
    }


    public static int[] getNext(char[] str2){
        int[] next = new int[str2.length];
        next[0]=-1;
        if (str2.length==1)return next;
        next[1]=0;
        /**
         * cn有两层含义:
         * 1.要和i-1处比较的字符的位置
         * 2.i-1处的next值(next[i-1]==cn)
         */
        int cn=0;
        int i=2;
        //这里cn和i也是对应的
        while (i<next.length){
            if (str2[i-1]==str2[cn]){//相等的话,在继承i-1处next值的基础上+1,同时cn。。。。
                next[i++]=++cn;
                /**
                 * cn=cn+1;  cn+1的原因是:个人理解------
                 * 0到cn 共有cn+1个字符  与  i-1到i-1-cn  的字符相同
                 *
                 * 其实,next数组存放的本来就是cn+1的位置,它本来在getIndexOf()中,就是要退到cn+1的位置的
                 *              p2=next[p2];
                 *      ********        *********
                 *             cn cn+1          i-1  i
                  * next[i++]=cn;
                 */

            }else {
                if (cn>0){  //往前跳,然后进行比较
                    cn=next[cn];
                }else{   //没法跳了,当前next值为0
                    next[i++]=0;
                }
            }
        }
        return next;
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值