KMPアルゴリズムはC ++で実装されています。

製品より転載は少しライブラリです:http://www.pinlue.com/article/2020/03/0417/469980519323.html

 

KMPアルゴリズム

KMPマッチングアルゴリズムは「クヌースモリス・プラット」提案マッチングアルゴリズムにより高速モードです。

ヒント:ユニークが最大長包括的にサブストリング

1.問題が解決される:Pを想定サブストリングを与えられ、Tは、これは、パターンマッチングと呼ばれる検索、およびTから部分全てPに対して同じ識別するように依頼される文字列です。(以下、Pと呼ばれ、Tは、ターゲット文字列と部分文字列である)(サブストリングは、T位置で与えられてもよいです)

私たちは例を見てみましょう:

T:T0 T1 T2 T3 .... TM-1 ... TN-1

P:P0 P1 P2 P3 ..... PM-1

TK = PK、そしてマッチが成功した作り、最もTを左から始める比較。

2.ソリューションパターンマッチングの問題:

A:単純なパターンマッチングアルゴリズム(アイデアはシンプルですが、シンプルなことに、長い時間が、そこにバックトラックされている):最も単純で直接的なアプローチは、T Pの文字の文字と比較するために、彼らは同じ文字ではありませんヒットが日付のTのうち、成功したか、到達Pの右端の文字があるまで、Pは、右の1文字、再比較されます

例えば:もしP = "aaaba"、T = "aaabbaaaba"、図以下マッチング処理。

T:aaabbaaaba

P:aaaba

aaaba

.....

aaaba

分析から難しいものではありません、最悪の場合は、「各キャラクターが先月に登場比較されて、M回まで比較トリップごとに、N-M + 1回、アップM *(Nとの比較の合計数まで比較-M + 1)」、0の時間複雑度(M * N)。ときP右にかかわらず、比較のトリップ中間結果は、したがって必然的なバックトラック(例:必須ではありません最初の3ビットシフトAAA)であるものの。ここで私は後戻りせずにKMPアルゴリズムを紹介します。

3.KMPアルゴリズムは、一致する主な問題点を解決するために:

A.文字列の比較は、Pは右でなければなりませんどのように多くの文字が、比較の前に次の旅行を決定するまで発生した場合。

B. P後最初と比較不平等でちょうど文字Tから文字を比較開始し続ける必要があり、右へ。

これは、パターンマッチングの単純な例を問題に私たちをリード。第1の比較工程において不良が最初の4つの文字Pが成功したことを示す最初の4文字のP、B、です。第3のパターンP Bの文字は、その最初の3つの文字(AAA)中に現れません。したがって、次の比較、移動は4つの文字Pに少なくともバックアップ時に、最後の文字の最初の文字でPの外観は同じであるので、最初の文字から再びPの後に右に4つの文字比較し、確かに同じではありません。魅力をまとめると:Pは、5つの文字で、右も、その後、0番目のPの文字とTさんから最初の5つの文字を比較開始する必要があります!

KMPコアアルゴリズム:KMPアルゴリズム次一致測距モードと開始比較の右側に位置Pの間に発生したときを決定する補助アレイによる。次の[I]パターンP自体についてのみ最初の項目のI + 1つの値にかかわらず、ターゲットTの マッチング処理は、Tjのに等しくない場合pIを遭遇し、次の[I]> = 0、Pは右I-NEXT [i]は、ビット文字でなければならない場合、Tjが第一次[i]は文字でPによって行われます。比較;場合:コンパレータで[I] = -1、任意の文字でPはもはやTjのと比較して、むしろ右PにP0及びTjの+ 1からI + 1つの文字と再び開始次の(5月)本当に理解していない自分自身の例を見つけるために、刑に直面し、それを試してみます

あれば、次のアレイが計算されたパターンPと関連するものとして、上記の意味によれば、容易に文字列照合アルゴリズムを与えることができます。(問題はとても変換します)

例えばA P = "01001010100001":C.nextを計算しました。

I:0 1 2 3 4 5 6 .....

P:0 1 0 0 1 0 1 .....

J(次の[I]):-1 0 0 1 1 2 3 .....

例えば1:我々は、最初の2つの文字0,1 P自体に関連する次の[2]の値が、考慮されたいです。ストリング01で、検索する「ほぼ同じ最大文字列を、それが次のように、文字の数は、文字列に含まれる[i]が値」0と1に等しくない場合、同じ文字列が存在しない場合、次の[Iそう] = 0;

このような2通り:私たちは、次の考慮されたい[6]の値は、6つの文字010010前にP自体に関連します。この文字列010は、同じ最大値= 010、文字列010については、数3です。だから、次の[I] = 3;

このような3通り:私たちは、次の考慮されたい[5]の値は、5つの文字01001の前にP自体に関連します。=この文字列01 01列01について同一の最大数は2です。だから、次の[I] = 2;

// KMP.h

テンプレート<クラスT>

クラスKMP

{

}。

テンプレート<クラスT>

INT KmpCompare(T源[]、int型ssize、T DEST []、INT DSIZE、INT P [])

{

int型J = -1;

以下のために(; I <ssize; int型私は0を= I ++)

{

一方、(j> = 0 && DEST [J + 1]!=源[i])と

J = P [J]。

IF(DEST [J + 1] ==ソース[i])と

J ++;

(J == DSIZE-1)の場合

{

IJ返します。

}

}

-1を返します。

}

テンプレート<クラスT>

ボイドKmpPreCompare(T源[]、INT P []、INT ssize)

{

P [0] = -1。

(; I <ssize; I ++ INTはI = 1、Jが= -1)のために

{

一方、(j> = 0 &&源[J + 1]!=源[i])と

J = P [J]。

IF(ソース[J + 1] ==ソース[i])と

J ++;

P [I] = J。

}

}

// KMPTest.cpp

書式#include <iostreamの>

#include "KMP.h"

名前空間stdを使用。

int型のmain(int型のargc、char型** ARGV)

{

char * A = "C:\ WINDOWS \ SYSTEM32; \プログラムファイル\のJava \ jdk1.7.0 \ binに;";

char * B = "D:\プログラムファイル\のJava \ jdk1.7.0"。

int型* P =新しいINT [5]。

KmpPreCompare(B、P、5); //宛先文字列が最初に再び見つけるためにプリコンパイルする必要があります

//戻りの位置インデックスであり、iがKmpCompare(strlenを()、B 5、P)は= SIZE_T

[] Pを削除します。

coutの<< I <<てendl;

0を返します。

}

公開された60元の記事 ウォン称賛52 ビュー110 000 +

おすすめ

転載: blog.csdn.net/yihuliunian/article/details/104658528