文字列マッチングのためのKMPアルゴリズム

文字列マッチングのためのKMPアルゴリズム

文字列の照合は、コンピューターの基本的なタスクの 1 つです。

たとえば、「BBC ABCDAB ABCDABCDABDE」という文字列がありますが、そこに「ABCDABD」という別の文字列が含まれているかどうかを知りたいのです。

[[72072]]

このタスクを実行できるアルゴリズムは多数ありますが、Knuth-Morris-Pratt アルゴリズム (略して KMP) は最もよく使用されるアルゴリズムの 1 つです。これは 3 つの *** にちなんで名付けられ、最初の K は有名な科学者の Donald Knuth に由来しています。

[[72073]]

このアルゴリズムは理解しにくいです。インターネット上には多くの説明がありますが、どれも読みにくいです。私は Jake Boxer の記事を読むまで、このアルゴリズムを本当に理解していませんでした。以下では、KMP アルゴリズムについて、私自身の言葉でより分かりやすく説明してみたいと思います。

1.

まず、文字列「BBC ABCDAB ABCDABCDABDE」の最初の文字が、検索語「ABCDABD」の最初の文字と比較されます。 B は A と一致しないため、検索語は 1 つ後ろの位置に移動します。

2.

B は A と一致しないため、検索用語は後ろに移動します。

3.

これは、文字列に検索語の最初の文字と同じ文字が含まれるまで続きます。

4.

次に、文字列の次の文字を検索語と比較します。これはまだ同じです。

#p#

5.

これは、検索語に対応する文字と異なる文字が文字列内に存在するまで続きます。

6.

この時点で、最も自然な対応は、検索語全体を 1 つ前の位置に移動し、最初から 1 つずつ比較することです。これは実行可能ですが、「検索位置」をすでに比較した位置に移動して再度比較する必要があるため、非効率的です。

7.

基本的な事実は、スペースが D と一致しない場合、最初の 6 文字が実際には「ABCDAB」であることがわかるということです。 KMP アルゴリズムの考え方は、この既知の情報を使用して、「検索位置」を比較された位置に戻すのではなく、後方に移動し続けることで効率を向上させることです。

8.

これをどうやって行うのでしょうか?検索用語の部分一致テーブルを計算できます。このテーブルがどのように生成されるかについては後で説明します。今は、使い方だけを知っておいてください。

9.

スペースはDと一致しないこと、そして最初の6文字「ABCDAB」が一致することがわかります。表から、最後に一致する文字 B に対応する「部分一致値」は 2 であることがわかります。したがって、後方に移動するビット数は次の式に従って計算されます。

シフト数 = 一致した文字数 - 対応する部分一致値

6 - 2 は 4 なので、検索語は 4 桁後ろに移動します。

10.

スペースが C と一致しないため、検索語をさらに後ろに移動する必要があります。このとき、一致した文字数は 2 (「AB」) であり、対応する「部分一致値」は 0 です。したがって、シフト数 = 2 - 0、結果は 2 なので、検索語は 2 つ後ろにシフトされます。

11.

スペースがAと一致しないため、1つ後ろに移動します。

12.

C と D が一致しないことがわかるまで、少しずつ比較します。したがって、シフト数 = 6 - 2 となり、検索語は引き続き 4 つ後ろにシフトされます。

#p#

13.

検索語の最後のビットが完全に一致すると判断されるまで、ビットごとに比較し、検索を完了します。検索を続行する場合(つまり、すべての一致を検索する場合)、移動された場所の数 = 7 - 0 となり、検索用語は 7 か所前に戻り、ここでは繰り返されません。

14.

部分一致テーブルが生成される仕組みを次に説明します。

まず、「プレフィックス」と「サフィックス」という 2 つの概念を理解する必要があります。 「プレフィックス」は、最初の文字を除く文字列の先頭の組み合わせ全体を指します。「サフィックス」は、最初の文字を除く文字列の末尾の組み合わせ全体を指します。

15.

「部分一致値」とは、「プレフィックス」と「サフィックス」の最長共通要素の長さです。 「ABCDABD」を例に挙げると、

  1. - 「A」の接頭辞と接尾辞は両方とも空集合であり、要素の合計の長さは 0 です。
  2.  
  3. - 「AB」の接頭辞は[A]、接尾辞は[B]、共通要素の長さは0です。
  4.  
  5. - 「ABC」のプレフィックスは[A、AB]、サフィックスは[BC、C]で、要素の合計長は0です。
  6.  
  7. - 「ABCD」のプレフィックスは[A、AB、ABC]、サフィックスは[BCD、CD、D]であり、共通要素の長さは0です。
  8.  
  9. - 「ABCDA」のプレフィックスは[A、AB、ABC、ABCD]、サフィックスは[BCDA、CDA、DA、A]、合計要素は「A」、長さは1です。
  10.  
  11. - 「ABCDAB」のプレフィックスは[A、AB、ABC、ABCD、ABCDA]、サフィックスは[BCDAB、CDAB、DAB、AB、B]、要素の合計は「AB」、長さは2です。
  12.  
  13. - 「ABCDABD」のプレフィックスは[A、AB、ABC、ABCD、ABCDA、ABCDAB]、サフィックスは[BCDABD、CDABD、DABD、ABD、BD、D]であり、共通要素の長さは0です。

16.

「部分一致」の本質は、文字列の先頭と末尾が繰り返される場合があることです。たとえば、「ABCDAB」には「AB」が 2 つあるため、「部分一致値」は 2 (「AB」の長さ) になります。検索語が移動すると、最初の「AB」は 4 桁 (文字列の長さ - 部分一致の値) 後方に移動し、2 番目の「AB」の位置に到達します。

オリジナルリンク: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

<<:  プログラミングアルゴリズムと人生の選択

>>:  文字列マッチングのためのボイヤー・ムーアアルゴリズム

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

Keras によるステートフル LSTM リカレント ニューラル ネットワークの理解

[[327815]]この記事を読むと、次のことがわかります。 1. シーケンス予測問題のための単純な...

...

...

GPU の在庫は 600,000 に達します!ザッカーバーグ氏、新たな目標を確認:汎用人工知能の創出

1 月 19 日、テクノロジー業界が超人的、神レベルの知能を達成する道を歩んでいるという確固たる信念...

...

組み込みアルゴリズムソートアルゴリズム

[[433624]] 1. バブルソートバブル ソートは、C 言語のシンプルな初級レベルのソート ア...

...

2022年のNature年次指数が発表され、最も急成長した50の機関のうち31は中国の機関です。

​たった今、2022年のNature年次インデックスレポートが発表されました。上位50の研究機関のう...

ベンチャー投資における機械学習の活用方法

過去 20 年間にわたり、Veronica Wu は多くの大きな技術的変化の始まりを目撃してきました...

...

内部テスト中です! Word、Excel、Outlookに機械学習が搭載される

マイクロソフトは、機械学習を使用して人々がより効率的に仕事を遂行できるよう支援する、多数の新機能を ...

...

ChatGPT は来週 6 つの主要なアップデートを予定しています。

公式発表では来週6つのメジャーアップデートが予定されているとのこと。早速見ていきましょう。写真1. ...

AIを実際にどのように実装するかまだ検討中ですか? OpenPOWERは未来がここにあることを伝えます

[51CTO.com からのオリジナル記事] モノのインターネットの普及とセンサーの広範な使用により...

機械学習について学びたい方はこちらをご覧ください。1ステップで専門家になる方法をお教えします!

パターン認識や機械学習のファンであれば、機械学習では避けられない重要な問題であるサポートベクターマシ...