【けーえむぴーほう】

KMP法 とは?

最終更新:
💡 一致済みの情報を使い、文字列の比較をやり直す量を減らす

文字列の完全一致検索で、既に一致した部分の情報を利用して比較のやり直しを減らすアルゴリズム。パターンを前処理し、テキスト長n、パターン長mに対してO(n+m)時間で検索できる。テキスト側の位置を巻き戻さずに進められる。

📌 このページのポイント
ABABの末尾「AB」を再利用する 本文 A B A B A B C 最初 A B A B C C ≠ A 再開 A B A B C 先頭を2文字ずらし、同じAを比較 接頭辞と末尾が一致する最長の長さ ABABC の表:0・0・1・2・0
緑のABは比較し直さず再利用する。青のAから比較を続け、本文の位置は巻き戻さない。表の値は、その接頭辞自身を除く最長一致部分の長さで、ずらす文字数そのものではない。
ひよこ ひよこ
素朴な文字列検索との違いは?
ペンギン先生 ペンギン先生
候補の開始位置を一文字ずつずらし、先頭から比較し直す方法では、同じ文字を何度も比べることがある。この方法は一致済みの部分を利用し、必要な比較だけを続けるんだ。
ひよこ ひよこ
失敗関数って何?
ペンギン先生 ペンギン先生
不一致の後、パターンのどこから比較を続けるかを決める情報だよ。表の表現には違いがある。一つの形は、各接頭辞について、それ自身を除いて先頭と末尾が同じになる最長部分の長さを記録するもの。ABABCなら順に0、0、1、2、0になるよ。
ひよこ ひよこ
具体的にはどこから再開するの?
ペンギン先生 ペンギン先生
テキストABABABCにパターンABABCを先頭から重ねると、ABABまで一致し、次のCとテキストのAが不一致になる。一致済みのABABの先頭と末尾はAB。そこでこの2文字を再利用し、同じテキストのAと、パターンの3文字目Aを比較する。テキストを巻き戻さず、先頭を2文字ずらした位置で一致が見つかるんだ。
ひよこ ひよこ
いつでも速いの?
ペンギン先生 ペンギン先生
前処理を含め最悪O(n+m)時間で済むのが特徴だよ。素朴な方法は最悪O(nm)。ただし短い入力では前処理や実装の費用もあり、毎回実測で速いとは限らない。完全一致検索の方法で、似た文字列や正規表現の条件をそのまま扱うものではないんだ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「クヌース・モリス・プラット法」って出てきたら「一致済みの情報を使い、文字列の比較をやり直す量を減らす」と思えばだいたいOK!
📖 おまけ:英語の意味
「Knuth–Morris–Pratt Algorithm」 = クヌース・モリス・プラット法
💬 Donald E. Knuth、James H. Morris Jr.、Vaughan R. Prattの姓をつないだ名前。1977年の論文Fast Pattern Matching in Stringsで説明されているよ。

参考資料

← 用語集にもどる