おおよその文字列検索の開始点は、レーベンシュタイン距離です。このアルゴリズムは、1つの単語を別の単語に変更するための単一文字の編集(挿入、削除、および置換)の数をカウントします。
この例はkitten
-> sitting
で、編集距離は3です。
- k itten-> s itten( 'k'を 's'に置き換えます)
- sitt e n-> sitt i n( 'e'を 'i'に置き換えます)
- sittin-> sittin g(末尾に「g」を追加)
このアルゴリズムにはバリエーションがあり、特に、2つの隣接する文字の転置を可能にするDamerau–Levenshtein距離があります(「hte」から「the」へのDL距離は1で、レーベンシュタイン距離は2です)。スペルチェック。ギャップが重要なアプリケーション(DNAストリング)には、他にもバリエーションがあります。
レーベンシュタイン距離はよく知られており、見つけるのはそれほど難しくありません(以前は、Oracleの関数としてそれを実装する必要がありました-すべてのデータをプルダウンしてからクエリコード側を実行するよりもはるかに高速でした)。Rosettacodeには、レーベンシュタイン距離の多数(54)の実装があります(一部の言語では、これを文字列ライブラリの一部としてどこかに持っています-Javaを使用している場合は、apache commons langを見てください)。 ウィキブックスには31の実装があり、2つを一目見ただけでは同じ言語の同じコードが表示されません。
これが機能する方法は、2つの文字列間の関係に対応する行列を作成することです。
.kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443
.
行と列は、ただ"空の文字列から各文字を挿入することにより、ターゲット文字列に得ることができることを表しています。これは理想的なケースではありませんが、アルゴリズムをシードするためにあります。
値がそのスポットと同じである場合( 'i' == 'i')、値は左斜め上方向の値と同じです。2つのスポットが異なる場合( 's'!= 'k')、値は最小値です。
- 上斜め左+ 1(置換)
- + 1の真上(挿入)
- すぐ左+ 1(削除)
編集距離の戻り値は、マトリックスの右下にある値です。
右下から左上に最小値で進むと、編集が完了したことがわかります。
.kitten
.0. .
s.1 .
i 1 .
t 1 .
t 1.
i.....2
n 2
g......3
これはかなりメモリ集約的なアプローチであることに注意してください。完全な行列を作成しないことで、メモリスコープを減らすことができます-アルゴリズムが扱うのはデータのサブセットであり、前の行(および現在の行で計算されたもの)を格納するだけでN*M
、2*max(N,M)
スペースからスペースに減らすことができます行)。 コードプロジェクトは、これを行う方法を示しています(ダウンロードするC#コードを使用)。