JAVAデータ構造とアルゴリズム:KMP

概要

KMPアルゴリズムが改善される文字列照合人々が呼び出すので、DEKnuth、JHMorrisとVRPrattによって提案されたアルゴリズム、クヌース - モリス - プラット操作(KMPアルゴリズムをいいます)。情報を用いてコアKMPアルゴリズムは高速マッチングの目的を達成するために、メインの文字列パターン文字列の一致の数を最小限にするために、一致しません。特定の実装()は、ローカルマッチング機能自体は、情報パターン文字列が含まれる次の機能によって実現されます。KMPアルゴリズムの時間複雑さ O(M + N)。

簡単な紹介

一致する文字列は、文字列の基本動作である、最も直接的な方法は、完全なバックトラックの検索を横断するが、その高い複雑さ、人々は効率性と一致し、一致を最適化しようとして、その複雑さをマッチング徐々に減少しています。
このプロセス、KMPの最も重要な部分では、彼はO元のアルゴリズムの複雑さを低減する(N + M)式中、n、mは二つの文字列の長さです。

詳細

最も直接的なバックトラック

左からスタート一致する文字列は、同じSC jを+1と同僚が発生した場合、すべてのマッチング処理は、SCに戻って運ば同じiが存在しない場合には、p個の添字に戻るには、ときトラバースされてまで。

public class Match_kmp {
    public static void main(String[] args) {
        System.out.println(indexOf("aaavbvdd","vbv"));
    }
    private static int indexOf(String s,String p){
        int i = 0;
        int sc = i;
        int j = 0;
        while (sc<s.length()){
            if(s.charAt(sc)==p.charAt(j)){
                j++;
                sc++;
                if(j==p.length()){
                    return i;
                }
            }else
            {
                i++;
                sc=i;
                j=0;
            }
        }
        return -1;
    }
}

その結果、第1試合は添字Iを返されます

  • 複雑さを解決するためのこの方法は、O(N * M)に達し、KMPアルゴリズムについて説明しました。

KMP試合

ダイヤグラム

1571297220130

同じJ ++、I ++、J同一でないバックトラッキング場合、①は、I = 0、右、J = 0に左一致します

②前回のバックトラック時に異なる試合は暴力が私に一致する場合++、J = 0ので、
私たちは、文字列を利用することができます前に、しかし、よりT、バックトラックのでした。これは、より多くの時間が複雑さを軽減しますです。jはマッチした文字列T [アレイ]の横のバックに依存します。前記アレイの下次解決.next = {0,0,0,0,2,2}に
シフト すばらしいです 小さな = n e x t [ j ] [j]は-nextマッチした文字列の右のサイズ=
この時点でjはまた、バックトラックされるので、次の[5] = 2、右サイズ= 5-2、
j = n e x t [ j 1 ] J =次の[J-1]
③ので、次にJ = 2;比較は[J-J = 2次バックトラック、同一でない

KMP

public class MatchKMP {
    public static void main(String[] args) {
        int ne[] =getNext("abcdabd");
        int res = kmp("ssdfgasdbababa","bababa",ne);
        System.out.println(res);
    }
    private static int kmp(String s,String t,int[] next){
        for (int i = 0,j=0;i<s.length();i++){
            while(j>0&&s.charAt(i)!=t.charAt(j)){
                j=next[j-1];
            }if(s.charAt(i)==t.charAt(j)){
                j++;
            }
            if(j==t.length()){
                return i-j+1;
            }
        }
        return 0;
    }
    private static int[] getNext(String t){
        int next[]=new int[t.length()];
        next[0]=0;
        for (int i = 1,j=0; i < t.length(); i++) {
            while (j>0&&t.charAt(j)!=t.charAt(i))
                j=next[j-1];
            if(t.charAt(i)==t.charAt(j))
                j++;
            next[i]=j;
        }
        return next;
    }
}

次のアレイを解きます

  • プレフィックスは、最後のものを除く文字の集まりです
  • 接尾文字の最初のセットに加えて、
    abcabdの接頭辞と接尾辞計算
    文字サフィックスが0になる前に
    、AB&接頭辞である[A] Aサフィックス[B] 0は同じである
    プレフィックスはABC [AB]接尾辞であります0と同じ【、C BC]で
    ABCAがある接頭辞[ABは、ABC]接尾辞である[BCA、CA、] 0
    プレフィックスabcab [AB、ABC、ABCA ] サフィックス[bcab、キャブは、 AB、B] AB次の[4] = 2と同じ最大
    プレフィックスabcabdある[AB、ABC、ABCB 、abcabd]
    サフィックス[bcabd、CABD、ABD、BD 、D] 次の最大全長またはABそれ[ 5] = 2;
  private static int[] getNext(String t){
        int next[]=new int[t.length()];
        next[0]=0;
        for (int i = 1,j=0; i < t.length(); i++) {
            while (j>0&&t.charAt(j)!=t.charAt(i))
                j=next[j-1];
            if(t.charAt(i)==t.charAt(j))
                j++;
            next[i]=j;
        }
        return next;
    }

概要

KMP学習アルゴリズムは、私は、読み出しが理解されていない場合は特に、多くの時間を費やしました。その後、彼自身の描画後、瞬時に理解し、物事はまだそれをしなければなりません。

参照

Baiduの百科事典KMPアルゴリズム

自分自身を描画し、瞬時に理解し、物事はまだそれをしなければなりません。

参照

Baiduの百科事典KMPアルゴリズム

ルアンYifengさんのブログ文字列マッチングアルゴリズムKMPを

公開された91元の記事 ウォンの賞賛9 ビュー10000 +

おすすめ

転載: blog.csdn.net/WeDon_t/article/details/102611537