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的分步匹配

这里写图片描述

i j 图解 执行操作 操作后i 操作后j
0 0 这里写图片描述 i++;j++ 1 1
1 1 这里写图片描述 i++;j++ 2 2
2 2 这里写图片描述 i++;j++ 3 3
3 3 这里写图片描述 j=next[j] 3 1
3 1 这里写图片描述 i++;j++ 4 2
4 2 这里写图片描述 i++;j++ 5 3
5 3 这里写图片描述 i++;j++ 6 4
6 4 j为4超过循环范围,退出 退出 6 4

求Next数组的分步解释

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

i k 图解 执行操作 操作后i 操作后k 操作后next数组
2 0 这里写图片描述 k=next[k] 2 -1 -1,0
2 -1 判断为-1 next[i++]=++k 3 0 -1,0,0
3 0 这里写图片描述 k=next[k] 3 -1 -1,0,0
3 -1 判断为-1 next[i++]=++k 4 0 -1,0,0,0
4 0 这里写图片描述 next[i++]=++k 5 1 -1,0,0,0,1
5 1 这里写图片描述 next[i++]=++k 6 2 -1,0,0,0,1,2
6 2 这里写图片描述 k=next[k] 6 0 -1,0,0,0,1,2
6 0 这里写图片描述 k=next[k] 6 -1 -1,0,0,0,1,2
6 -1 判断为-1 next[i++]=++k 7 0 -1,0,0,0,1,2,0
7 0 这里写图片描述 k=next[k] 7 -1 -1,0,0,0,1,2,0
7 -1 判断为-1 next[i++]=++k 7 0 -1,0,0,0,1,2,0,0

猜你喜欢

转载自blog.csdn.net/qq_38345606/article/details/80296511