スペルが異なる(完全に異なるわけではない)人の名を含むJavaの文字列のリストがあります。たとえば、JohnはJon、Jawn、Jaunなどのスペルである可能性があります。このリストで最も適切な文字列を取得するにはどうすればよいですか。この場合、Soundexの使用方法を誰かが提案できれば、非常に役立ちます。
5 に答える
近似文字列マッチングアルゴリズムを使用しています。これを実装するには、いくつかの戦略があります。Blurは、レーベンシュタインの単語距離に基づく近似文字列マッチングのTrieベースのJava実装です。
いわゆるボイヤームーア近似文字列マッチングアルゴリズムを実装する別の戦略があります。
このアルゴリズムとレーベンシュタインワード距離を使用してこれらの問題を解決する通常のアプローチは、入力を可能な出力と比較し、目的の出力までの距離が最も短いものを選択することです。
おおよその文字列を照合するためのjarファイルが1つあります。
リンクをたどってfrej.jarをダウンロードしてください
http://sourceforge.net/projects/frej/files/
このjarファイル内に1つのメソッドがあります
Fuzzy.equals("jon","john");
このタイプの近似文字列ではtrueを返します。
テキストの索引付け中に音声フィルター・ファクトリを使用する場合、Solrはこれを行うことができます。
検索するのはsolrの専門です。そして、似たような単語を検索します。ただし、これだけが必要で、solrが提供する他の機能が必要ない場合は、ここで入手できるソースを使用できます。
2つの文字列の一致を推定するための理論と方法はたくさんあります
「jon」は実際には「john」と等しくないため、鈍いtrue / falseの結果を与えることは奇妙に思えます。これは近いですが、一致しません。
かなりの数の推定方法を実装する1つの優れた学術研究は、「SecondString.jar」と呼ばれます-サイトリンク
ほとんどの実装されたメソッドは、一致にある程度のスコアを与えます。このスコアは、使用されたメソッドによって異なります。
例:「距離の編集」を、str2に到達するためにstr1で必要な文字の変更の数として定義しましょう。この場合「jon」->「john」は、この方法では当然1文字の追加が必要です。スコアが低いほど良いです。
この記事では、近似文字列マッチングのTrieベースのJava実装に関する詳細な説明と完全なコードを提供します 。Trieを使用した高速で簡単なレーベンシュタイン距離。
検索関数は、指定された単語よりも少ないすべての単語のリストを返します
ターゲットワードからの最大距離
def search(word、maxCost):
# build first row
currentRow = range( len(word) + 1 )
results = []
# recursively search each branch of the trie
for letter in trie.children:
searchRecursive( trie.children[letter], letter, word, currentRow,
results, maxCost )
return results
この再帰ヘルパーは、上記の検索機能で使用されます。それは
previousRowはすでに入力されています。
def searchRecursive(node、letter、word、previousRow、results、maxCost):
columns = len( word ) + 1
currentRow = [ previousRow[0] + 1 ]
# Build one row for the letter, with a column for each letter in the target
# word, plus one for the empty string at column 0
for column in xrange( 1, columns ):
insertCost = currentRow[column - 1] + 1
deleteCost = previousRow[column] + 1
if word[column - 1] != letter:
replaceCost = previousRow[ column - 1 ] + 1
else:
replaceCost = previousRow[ column - 1 ]
currentRow.append( min( insertCost, deleteCost, replaceCost ) )
# if the last entry in the row indicates the optimal cost is less than the
# maximum cost, and there is a word in this trie node, then add it.
if currentRow[-1] <= maxCost and node.word != None:
results.append( (node.word, currentRow[-1] ) )
# if any entries in the row are less than the maximum cost, then
# recursively search each branch of the trie
if min( currentRow ) <= maxCost:
for letter in node.children:
searchRecursive( node.children[letter], letter, word, currentRow,
results, maxCost )