KMPアルゴリズムは、最も詳細なアイデアを左に神の最も伝統的であるJAVA

この記事では、研究の要約である、あなたのすべての尖ったアウトを歓迎するために、エラーがあるかもしれません。再投稿。

タイトル:文字列と文字列str1はSTR2、STR1内の文字列内の文字列STR2(0から始まる)の最初の発生を見つける考えます。ない場合は、-1を返します。

str1 = aaaaabcabc

str2 = abcabcaa

神の左に付随接触前にいくつかの時間は3日間程度、ビデオアルゴリズムを説明し、繰り返し3回KMPアルゴリズムを見ています。最後に、私たちは自分の理解と経験のいくつかを持っていました。行うには、伝統的なKMP文字列照合アルゴリズムは、実際には、暴力の最適化アルゴリズムの配列に隣接しています。別の理解は、ここでは詳細に説明しないが、ダイナミックプログラミングアルゴリズムKMPとして理解されるべきです。

私は3つの部分に分かれ、ここで話しています。

  1. 暴力ソリューション
  2. KMPアルゴリズム
  3. 次の配列を取得する方法

暴力ソリューション

暴力アルゴリズムは、詳細の一部に対処するため、実際のコーディングと必要性を非常にシンプルに見えますが、それはについて書くことをお勧めします。ここでSTR2へのポインタI、JポインタにSTR1。1 - iが0である最初の初期位置は、初期位置は最後str1.lengthあります。

  1. i及びjはバック1動かされる:0009 [I]とstr2 [j]はに等しいです。

  2. 0009 [I]とstr2 [J]不等、Jリターン0、iが次の比較から初期位置を開始します。

この位置へJ長がstr2.lengthに0ビット目から記述することができる場合 - 1ビットが既に等しい、ケースリターンI - jを、第1位置指標はSTR1にSTR2に存在します。

私は最終的にstr1.lengthである初期位置に達した場合 - 一致がないこの時点では、1を、この説明は常にSTR2への道と一致しませんでした。この時間は、-1を返します。

コード:

public int strStr(String str1, String str2) {
    int length1 = str1.length();
    int length2 = str2.length();
    if(length2 == 0) return 0;
    if(length1 < length2) return -1;
    int i = 0;
    while(i < length1){
        int j = 0;
        while(i < length1 && j < length2
        && str1.charAt(i) == str2.charAt(j)){
            i++;
            j++;
        }
        if(j == length2){
            return i-j;
        }
        i = i - j + 1;
    }
    return -1;
}

手がについて書くことをお勧めします。

KMPアルゴリズム

ここにされていない方法を次議論することです。あなたは情報の一部はSTR2に保存されているかを知る必要があります。プレフィックス文字列はすべての彼のstr2の最大のサフィックスに等しい形成された文字の前に等しいです。ここで説明するために例えば傷は、次のとおりです。

文字列があった場合、インデックスは6に等しいですa b c a b c

接尾辞の前に撮影したときは、接頭辞があり、サフィックスは、ケースの範囲、Cです。1次取ることはできません。

2は、2次の接頭辞と接尾辞、AB&接頭辞、接尾辞BCは、取ることができないときに行われます。

3時に接頭辞と接尾辞、接頭辞ABC、ABCの接尾辞取られ、この時間はに等しく、次の取ることができます。

接頭辞と接尾辞は、ABCA接頭辞、接尾辞CABC、4次を取ることができないとき4で撮影しました。

5時に接頭辞と接尾辞、接頭abcab、接尾bcabc取られ、次の5を取ることはできません。

図6は、接頭辞と接尾辞を取ることができません。かつての缶がサフィックス文字列そのものではないので。

index:0 1 2 3 4 5 6 7 8 9

str1 = a a a a a b c a b c

str2 = a b c a b c a a

next:-1 0 0 0 1 2 3 1

次は、プロセスKMPアルゴリズムです。暴力に基づいて解決策は、我々はまだ二つのポインタiとjを持っています。

  1. 2つの要素がある場合に等しく:iとj後退。
  2. 等しくない二つの要素:J =次の[j]が、この時点で次のページ[j]は、ポインタjは前面に移動されたことを示す、-1に等しい場合。

我々は慎重に困難があり、これはどちらの場合も同じではありません理解しています。

next[j] != -1この場合、Jポインタは直接ジャンプすることstr2[next[j]]に。なぜそう?たとえば、子供のために。

指数 0 1 2 3 4 5 6 7

STR1 = a b c f a b c x

STR2 = a b c f a b c y

次回=-1 0 0 0 0 1 2 3

、私はJ = 7は、二つの要素が等しくないこの時間は、我々はjにジャンプします=ときのインデックスでは、6だったstr2[next[j]]、それはありますj = 3サブストリングとサブストリングSTR1のSTR2の前部の前に、この時間は等しく、それらは共通の次配列を共有します。Jジャンプ3に、これが表し:Y / Xこのサブストリングの前の最初の3つの最後の3つは同じ彼です。それらが等しいとき3が黙認のでので、Yの最初の3と最後の3桁がサブストリングのxは、当社のサブストリングは、この時点で、比較する必要はありませんされていません。次いで、トップスリー(012の指数)は、第4(指標3)ビットの直接比較を比較する必要はありません。ここでは、次のコア配列です。神の左ビデオでは、より直感的に語っています。

STR1 = a b c f a b c x

STR2 = * * * * a b c f a b c y

Xの比較は、Fに等しいです。

next[j] == -1この場合、jは最前線に来ていない、と前進し続けるする方法なので、私は後方に移動することができました。

コード:
public static int getIndexOf(char str1[], char str2[]) { if(str1.length == 0 || str1.length < str2.length) { return -1; } if(str2.length == 0) { return 0; } int i = 0; int j = 0; int next[] = getNextArray(str2); //对应三种情况 while( i < str1.length && j < str2.length) { if(str1[i] == str2[j]) { i++; //两个元素相等 j++; }else if(next[j] == -1) { i++; //next[j] == -1 }else { j = next[j];//next[j] != -1 } } return (j == str2.length) ? i-j : -1; }
##次アレイ

STR2 = a b c f a b c y

次回=-1 0 * * * * * *

最初のデフォルトは-1です。最初の要素は何の部分文字列を持っていないので。

第二は、0にデフォルトビット。2番目の文字列の子要素が一つだけの要素である、そしてので彼はプレフィックスとサフィックスの最大数に等しいことだけ0にすることができます。

次に第三のある、第三のサブストリングでありa b、これは困難です。どのようにその次の値を見つけるために。j = 3

次の値の1、 - jにcn = next[j-1]対応する要素STR2、及びstr2[j-1]比較。ここで、CN = 0、すなわち、1番元素と比較元素番号0の値です。そこに2例の比較は等しい、等しくないでなければなりません。不均等な時間でも2例。

指数 0 1 2 3 4 5 6 7

STR2 = a b c f a b c y

次回=-1 0 0 0 0 1 * *

より直感的に、私別の例を参照してください。J = 6。

cn = next[j-1] = 1, str2[cn] = b

str2[j-1] = b

この時間は、それゆえ、同じですnext[6] = ++cn = 2なぜ?

この表すCNは何ですか?CNが代表であるj-1ビットを次の値は、その値を表すj-1接頭辞と接尾辞ビット最大。最大値は、彼が最初であり、最後に等しいことを示し、1です。次いで、(二度目の比較str2[cn])、次の(最後のビットstr2[j-1])は等しいです。イコール、next[6] = ++cn = 2行うにはどのように不平等な?2例に分け。

  1. cn > 0,cn = next[cn]
  2. cn<= 0,next[j] = 0

ここで、サブサブ文字列の場合に継続する、と見つけることが理由ですstr[j-1]等しいがcnそれを見つけていない場合は、?それを行う方法next[j] = 0

コード:

public static int[] getNextArray(char []str) {
    if(str.length == 1) {
        return new int [] {-1};
    }
    int next[] = new int [str.length];
    next[0] = -1;
    next[1] = 0;
    int i = 2;
    int cn = 0;
    while( i < str.length) {
        if(str[i-1] == str[cn]) {
            next[i++] = ++cn;
        }else if(cn > 0) {
            cn = next[cn];
        }else {
            next[i++] = 0;
        }
    }
    return next;
}

何の概要

  1. 暴力的な解決策、そしてより多くの書き込みには、それが二回熟練書きます。
  2. KMPの特定の実装では、3例があります。要素、要素及び次の範囲に等しい-1に等しくないが、に等しい次の要素不等-1。
  3. 次の方法を解決するだけでなく、3例。CNとj-1は、対応する要素、及びCN> 0の範囲の対応する要素、及び不等CN <= 0の対応する要素と同じです。

いいえのStuI公共更新同期アルゴリズム学習プロセス、歓迎の注意。

おすすめ

転載: www.cnblogs.com/stul/p/11815913.html