KMPアルゴリズムに

データ構造の最近のレビューでは、アルゴリズムは、KMPの章を学んだ、それは混乱し、私はこのアルゴリズムを学ぶための最初の時間を覚えているようで、教師が教室でTuomohengfeiを話す、非常に情熱、そして私たちは、下記をご覧聞きますより無知な、何?そのアルゴリズムは何ですか?地獄?Goは本を読んで、完全にそれを理解していませんか?要するに、私はいくつかのビデオやブログで非常に無知比、放課後の外観を感じ、ゆっくりと学習が容易ではない、もう少し理解していて、地上に降り動作する必要があります。3年後、このアルゴリズムを再勉強、真剣にこのアルゴリズムを研究するために、本やビデオをピックアップして、まだ、理解は十分徹底し、非常に明確ではないようです。

アルゴリズムに1.KMP紹介

モリス - - プラットアルゴリズム、KMPアルゴリズム、DEKnuthと呼ばKMPアルゴリズムは3つの研究、避け繰り返しトラバーサル、フルネームがクヌートと呼ばれていることを巧妙なアルゴリズムの結果は、ベテラン(DEKnuth、JHMorrisとVRPratt)によって開発されました、として知られているコンピュータ分野におけるこの作品の完成第四巻「コンピュータプログラミングのアート」の準備「相対性理論。」

アレイ次のサブストリングの2計算

 KMPアルゴリズムのキーポイントは次の[]配列、のみに関連する次の文字列パターンマッチングを持つ配列、例えば、「abababca」サブストリングを計算し、その次の配列を見つけることです

添字開始インデックス= 0、

インデックス= 0、「」接頭辞と接尾辞である空集合、値= 0。

インデックス= 1、「AB」接頭辞と接尾辞は、「a」および「b」は、値= 0に等しくありません。

インデックス= 2、接頭辞「ABA」は「」、「AB」、サフィックスは「BA」であり、「」、同じ交差点「」、1の長さ、値= 1です。

インデックス= 3、接頭辞 "ABAB" は ""、 "AB"、 "ABA"、接尾辞 "BAB"、 "AB"、 "B"、最長 "AB" の交点、2の長さ、値と同じです= 2;

インデックス= 4、接頭辞 "アベバは" ""、 "AB"、 "ABA"、 "ABAB"、接尾辞 "ババ"、 "ABA"、 "BA"、 ""、最大同じ交差点「ABAあります」、3、値= 3の長さ。

インデックスは= 5、接頭辞 "ABABABは、" ""、 "AB"、 "ABA"、 "ABAB"、 "アベバ"、接尾辞 "babab"、 "ABAB"、 "BAB"、 "AB"、「Bであります「最長同一の交差点」ABAB」、4の長さ、値= 4。

インデックスは= 6、 "abababc" プレフィックスは「、 ""、 "AB"、 "ABA"、 "ABAB"、 "アベバ"、 "ABABAB"、接尾辞 "bababc"、 "ababc"、 "babc" ABCです"" BC "" C」、同じ交差点、値= 0ではありません。

インデックス= 7、接頭辞 "abababcaは、" ""、 "AB"、 "ABA" は、 "ABAB"、 "アベバ"、 "abababc"、接尾辞 "bababca"、 "ababca"、 "babca"、「ABCAです"" BCA "" CA "" "同じ交差点"」、1の長さ、値= 1。

次のように最終的な結果は以下のとおりです。

CHAR:| | B | | B | | B | C | |

インデックス:| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

値:| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |

次の[]アレイを使用する方法3、

長さは、[partial_match_length]次の部分一致partial_match_length、及びテーブルを発見した場合、一致の重複を避けるために、次の配列を使用して、ターゲット文字列マッチングで得られたサブストリングの次の後続のアレイは、既に、次の配列を使用して要素を整合さ> 1、我々 partial_match_lengthはスキップすることができます - 次の[partial_match_length-1]の文字を

文字が一致した=合計シフトビット数 - 部分一致に対応する値

CHAR:| | B | | B | | B | C | |

インデックス:| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

値:| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |

「bacbababaabcbab」には最初の一致、調整された位置のインデックス= 1、以下、マッチング処理の一例です

bacbababaabcbab

  |

  abababca

簡単には、整合部の長さはpartial_match_length = 1であることがわかり、それだけには次に[partial_match_length - 1] = 0、すなわち、次[0] = 0、この要素は、我々は、任意の要素、及び次のCBをスキップしないように試合が行われ、次の試合に、右に直接一致していません。

bacbababaabcbab

        | | | | |

     abababca

partial_match_length = 5、次の[partial_match_length - 1]、5であるこの時点で、部分一致長を見つける、この場所に来=次の[4]、アクセス手段次配列、次の[4] = 3、チェック次のように次の試合になるべきであるので、2つの文字をスキップし、= 2 3 - 次の[partial_match_length-1]、即ち、5 - - 次の[4] = 5、我々はpartial_match_lengthをスキップするダウンマッチング:

bacbababaabcbab

        XX | | |

         abababca

xxは、マッチング部3の長さをスキップ示し、partial_match_length = 3、次の[partial_match_length - 1] =次の[2] = 1、次のマッチングにスキップ 

partial_match_length - 次の[partial_match_length - 1]、すなわち、3 - 次のように= 2 1、2つの文字の後にスキップのマッチングは次のとおりです。

bacbababaabcbab

            XX | 

             abababca

部分的に長さが一致partial_match_length = 1、次の[partial_match_length - 1]、1 = 0、次の文字は、残りのメインストリングよりも長くなるように、一致する文字列を右マッチと一致しないスキップし、一致する文字列が検出されません。

 

 

4、KMPアルゴリズムはC言語を使用してコードに実装しました

する#include <stdio.hに> 
する#include <STDLIB.H> 
の#include < 文字列・H>
 ボイド GET_NEXT(CHAR T []、INT次の[])// 次数组
{
     INT I、J。
    I = 0 ; //  
    J = 1 ; //  
    、次の[ 1 ] = 0 ;
    一方、(J <T [ 0 ]){
         場合(I == 0 || T [I] == T [J])
        { 
            I ++ 
            J++ ; 
            次の[J] = I。
            / * IF(!T [I] = T [J])
            { 
                次の[J] = I。
            } 
            { 
 
                次の[J] =次の[I]。
            } * / 
        } 
         
        { 
            iは = 次の[I]。
        } 
    } 
} 
int型 Index_KMP(CHAR S []、CHAR T [])
{ 
    int型の次の[ 1000年]。
    int型私は= 1 ;
    int型J = 1 ; 
    GET_NEXT(次T、)。// 获得次数组
    / * 
    (I = 1; I <= T [0]; I ++)のために
    { 
            のprintf( "%dの"、[I]次); 
    } 
    * / 
    ながら(I <= S [ 0 ] && J <= T [ 0 ])
    { 
        場合(j == 0 || S [I] == T [J])
        { 
           I ++ 
           J ++ ; 
        } 
         
        { 
            J = 次の[J]。
        } 
    } 
    もし(J> T [ 0 ])
        戻りそれを[ 0 ]。
    リターン 0 ; 
 
} 
int型のmain(){
     文字 T [ 1000年 ]、S [ 1000年]。
    int型私は、kは、
    一方、(scanf関数(" %S%S "、S、T)=!EOF)
    { 
        K = (T)strlenを。
        (; I> iが(T)strlenを。= 0 ; i--)// 向后移动
        { 
            T [i]は = T [I- 1 ]。    
        } 
        T [ 0 ] =  K。
        K = strlenを(S)。
        (; I> i)はS(strlenを。= 0 ; i--)// 向后移动
        { 
            S [i]は = S [I- 1 ]。    
        } 
        S [ 0 ] = K。
        printf(" %dの\ n " 、Index_KMP(S、T))。
    } 
    戻り 0 
 
}

 

結果は以下の通りであります:

 

 文字列の最初の発生の4は、数値指標開始と一致します

5、個人的な概要

 私は再び練習を再度ので、KMPアルゴリズムのこの演習の後、KMPアルゴリズム上のステップのいくつかは、いくつかの場所で、特に理解したい、そしておそらくこれはギャップがあるなかったが、まだ非常に明確ではありません。今日、いくつかのコードのバグがあった、バグがC言語の使用を再勉強し、いくつかのサイトを解決するために、情報を確認し、非常に完全な今日でした。

私のマイクロチャネル公共数の懸念へようこそ:

参考文献:

http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/

http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

https://liam.page/2016/12/20/KMP-Algorithm/

https://blog.dotcpp.com/a/8986

おすすめ

転載: www.cnblogs.com/zhuixun/p/11836375.html