KMPが欲しい
アルゴリズムkmp_search:入力:文字の配列、S(検索対象のテキスト)文字の配列、W(検索された単語)出力:整数(Wが見つかるSのゼロベースの位置)
define variables:
an integer, m ← 0 (the beginning of the current match in S)
an integer, i ← 0 (the position of the current character in W)
an array of integers, T (the table, computed elsewhere)
while m+i is less than the length of S, do:
if W[i] = S[m + i],
if i equals the (length of W)-1,
return m
let i ← i + 1
otherwise,
let m ← m + i - T[i],
if T[i] is greater than -1,
let i ← T[i]
else
let i ← 0
(if we reach here, we have searched all of S unsuccessfully)
return the length of S
複雑:
テーブルTが以前から存在していると仮定すると、クヌース-モリス-プラットアルゴリズムの検索部分の複雑さはO(k)です。ここで、kはSの長さ、Oはbig-O表記です。関数の開始と終了で発生する固定オーバーヘッドを除いて、すべての計算はwhileループで実行され、このループの反復回数の限界を計算します。これを行うために、最初にTの性質について重要な観察を行います。定義上、S [m +i]をW[i]と比較しているときに、S[m]で開始された一致が失敗した場合にTが失敗するように構成されます。次に、可能な一致はS [m +(i --T [i])]で開始する必要があります。特に、次に可能な一致はmよりも高いインデックスで発生する必要があるため、T[i]<iとなります。この事実を使用して、ループが最大2k回実行できることを示します。各反復で、ループ内の2つのブランチのうちの1つを実行します。最初の分岐は常にiを増加させ、mを変更しないため、現在精査されているSの文字のインデックスm+iが増加します。2番目のブランチはmにi--T[i]を追加します。これまで見てきたように、これは常に正の数です。したがって、現在の潜在的な一致の開始位置mが増加します。ここで、m + i = kの場合、ループは終了します。したがって、ループの各分岐は、それぞれm + iまたはmのいずれかで増加し、m≤m+ iであるため、最大でk回到達できます。m= kの場合、確かにm +i≥kであるため、増加します。せいぜい単位の増分で、過去のある時点でm + i = kを持っていたに違いないので、どちらの方法でも実行されます。したがって、ループは最大2k回実行され、検索アルゴリズムの時間計算量がO(k)であることを示しています。
追加情報:
KMPアルゴリズムの効率
アルゴリズムの2つの部分は、それぞれO(k)とO(n)の複雑さを持っているため、アルゴリズム全体の複雑さはO(n + k)です。これらの複雑さは、WまたはSにいくつの反復パターンがあっても同じです。