KMP子字符串查找算法

KMP子字符串查找算法

概述

算法的基本思想是:當出現不匹配時,就能知曉一部分文本的內容,可以利用這些信息避免將指針回退到所有這些已知的字符串之前。

DFA(確定有限狀態機)模擬

提前判斷如何重新查找,而這種判斷只取決於模式本身,所以可以對模式的字符序列做一個確定有限狀態機。

DFA的數據結構表示爲二維數組dfa[R][M],其中R爲指定字典中的字符集的個數(比如ASCII爲256),M爲匹配字符串pat的長度,狀態的意思是文本中某個位置i匹配pat的程度,0狀態爲未匹配狀態,M狀態爲終止狀態,找到了完整匹配的字符串。
如圖中R=3,M=6,二維數組中的值指向下一個狀態。

構造DFA

窮舉模式pat的所有可能情況,將這些情況用狀態圖表示。其中X記錄匹配失敗時重啓的索引位置。

編碼實現

用暴力算法實現子字符串查找算法


      public int search(String txt, String pat) {
        int i, N = txt.length();
        int j, M = pat.length();

        for (i = 0, j = 0; i < N && j < M; i++) {
            if (txt.charAt(i) == pat.charAt(j)) {
                j++;
            } else {  //顯式回退
                i-=j;
                j=0;
            }
        }

        if (j==M) return i-M;
        return N;
    }

KMP查找


    /**
     * @return pat在txt中開始出現的位置,如果等於txt.length()表示沒有找到
     */
    public int search(String txt) {
        int M = pat.length();
        int N = txt.length();

        int i, j;  //i指向txt,j指向pat
        for (i = 0, j = 0; i < N && j < M; i++) {
            j = dfa[txt.charAt(i)][j];
        }
        if (j == M) return i - M;   //匹配
        return N;                   //不匹配

    }

構造DFA


    private final int R;       // the radix
    private int[][] dfa;       // the KMP automoton

    private String pat;

    public KMP(String pat) {
        this.R = 256;   //設置字典大小
        this.pat = pat;

        //構造pat對應的dfa
        int M = pat.length();
        dfa = new int[R][M];
        dfa[pat.charAt(0)][0] = 1;
        for (int X = 0, j = 1; j < M; j++) {  //X記錄匹配失敗時的索引位置,j指向pat

            for (int c = 0; c < R; c++) {   //對於匹配失敗的情況,直接複製重啓狀態
                dfa[c][j] = dfa[c][X];
            }

            dfa[pat.charAt(j)][j] = j + 1;           //匹配成功的指向下一個狀態

            X = dfa[pat.charAt(j)][X]; //更新重啓位置X
        }

    }

優缺點

優點:適合在長度不確定的輸入流中進行查找,不需要在輸入中回退。
缺點:最壞的情況(在重複性很高的文本中查找重複性很高的模式)在實際應用中很少出現,還不如使用暴力算法來的容易,性能也差不了多少。

參考

Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章