32-咸鱼学Java-KMP字符串匹配算法Java版

简介

KMP算法相比于BF算法其最优点为,不用回退i,而且每次的j的回退根据next数组进行最优回退

代码

KMP

/**
     * KMP核心算法
     * @param str 
     * @param sub
     * @return
     */
    public static int KMP(String str,String sub)
    {
        //先判断是否符合规范
        if(str.length()<sub.length())
        {
            return -1;
        }
        //机获得Next数组
        int [] next = getNext(sub);
        //sub下标位置
        int j=0;
        //str的下标位置
        int i=0;
        //直到i,j超出下标
        while(i<str.length()&&j<sub.length())
        {
            //如果str和sub的当前元素相等,则i和j同时移动
            //j=-1为,如果在匹配第一个失败的时候,进行回退会回退到-1位置,数组会越界,所以直接向后移动
            if(j==-1||str.charAt(i)==sub.charAt(j))
            {
                i++;
                j++;
            }
            //否则j根据next数组进行回退,i不回退
            else
            {
                j = next[j];
            }
        }
        //如果j大于sub数组,则说明查找成功了,返回第一个找到的第一个下标
        if(j>=sub.length())
        {
            return i-j;
        }//如果没找到,返回-1
        else
        {
        return -1;
        }
    }

求Next

/**
     * 求Next数组
     * @param sub 要匹配的字符串
     * @return Next数组
     */
    public static int[] getNext(String sub)
    {   //创建一个数组
        int[] next = new int[sub.length()];
        //初始化
        next[0] = -1;
        next[1] = 0;
        //当前要求next的位置
        int i = 2;
        //k位置
        int k =0;
        //循环直到最后一个节点
        while(i<sub.length()-1)
        {
            //如果k=-1或者两元素相等
            if(k==-1||sub.charAt(k)==sub.charAt(i-1))
            {
                //当前的next大小等于前一个next+1
                next[i++] = ++k; 
            }//如果不相等,进行回溯,寻找可以匹配的最小子串
            else
            {   
                k = next[k];
            }
        }
        //返回next数组
        return next;
    }

KMP的分步匹配

这里写图片描述

ij图解执行操作操作后i操作后j
00这里写图片描述i++;j++11
11这里写图片描述i++;j++22
22这里写图片描述i++;j++33
33这里写图片描述j=next[j]31
31这里写图片描述i++;j++42
42这里写图片描述i++;j++53
53这里写图片描述i++;j++64
64j为4超过循环范围,退出退出64

求Next数组的分步解释

题目为
abcabdca
答案为
-1,0,0,0,1,2,0,0

ik图解执行操作操作后i操作后k操作后next数组
20这里写图片描述k=next[k]2-1-1,0
2-1判断为-1next[i++]=++k30-1,0,0
30这里写图片描述k=next[k]3-1-1,0,0
3-1判断为-1next[i++]=++k40-1,0,0,0
40这里写图片描述next[i++]=++k51-1,0,0,0,1
51这里写图片描述next[i++]=++k62-1,0,0,0,1,2
62这里写图片描述k=next[k]60-1,0,0,0,1,2
60这里写图片描述k=next[k]6-1-1,0,0,0,1,2
6-1判断为-1next[i++]=++k70-1,0,0,0,1,2,0
70这里写图片描述k=next[k]7-1-1,0,0,0,1,2,0
7-1判断为-1next[i++]=++k70-1,0,0,0,1,2,0,0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值