算法-KMP

    KMP算法的做用在于在一个主串中查找一个主串。算法

传统查找子串的方法是一个字符一个字符的比较,代码以下:数组

 public static int notKMP(String main,String sub){

        for (int i=0;i<main.length();i++){
            int j=0;
            int k=i;
            while (main.charAt(k)==sub.charAt(j)){
                k++;
                j++;
                if (j==sub.length()){
                    return i;
                }
            }
        }
        return -1;

    }

这种方式在遇到不相同的时候,主串往下移动一位,子串恢复到0.继续的进行对比。

spa

KMP的算法的有点在于子串中若是有相同的部分的话,那么能够省略一部分的校验,下面这个图加深一些印象:code

若是咱们使用KMP算法的话,那么中间的红框的那部分是不须要比较的,很显而易见,由于他们都第一步进行了比较了,固然怎么判断仍是须要算法的。blog

算法的步骤分为两部分,第一部分是算出子串的next数组,这个数组表达的就是子串的类似度,具体算法实现:get

 /**
     * 返回KMP数组
     * @param str
     * @return
     */
    public static int[] getNextArr(String str){
        int[] nexts=new int[str.length()];
        //j=1 的时候为0  j=2的时候为1
        nexts[0]=0;
        nexts[1]=1;
        for (int j=2;j<str.length();j++){
            int index=1;
            for (int i=0;i<j-1;i++){
                if(str.substring(0,i+1).equals(str.substring(j-i-1,j))){
                    index++;
                }
            }
            nexts[j]=index;
        }
        return nexts;
    }

第二部分就是进行匹配:string

 /**
     *
     * @param s 主串
     * @param t 子串
     * @param pos 从主串哪一个位置开始匹配
     * @return
     */
    public static int indexKMP(String s,String t,int pos){
        int i=pos;
        int j=0;
        int[] nexts=getNextArr(t);
        while (i<s.length()&&j<t.length()){
            if (j==0||s.charAt(i)==t.charAt(j)){
                i++;
                j++;
            }else {
                j=nexts[j-1];
            }
        }

        if (j>=t.length()){
           return i-t.length();
        }
        return 0;
    }

. 总的来说就是只关注子串,出现相同的那部分能够不进行比较。class

相关文章
相关标签/搜索