我在Java中有一个字符串列表,其中包含具有不同拼写的人的名字(并非完全不同)。例如,John可能拼写为Jon,Jawn,Jaun等。我应该如何检索此列表中最合适的字符串。如果有人能在这种情况下建议如何使用Soundex的方法,它将会有很大的帮助。
答案 0 :(得分:4)
您使用了approximate string matching算法,有几种策略可以实现这一点。 Blur是基于Levenshtein字距离的基于Trie的Java近似字符串匹配实现。 you can find the implementation at github here
还有另一种策略来实现其所谓的boyer-moore近似字符串匹配算法。 Here is the Java code for that
使用此算法和Levenshtein字距离解决这些问题的常用方法是将输入与可能的输出进行比较,并选择与所需输出距离最小的输出。
答案 1 :(得分:4)
有一个用于匹配近似字符串的jar文件..
浏览链接并下载frej.jar
http://sourceforge.net/projects/frej/files/
这个jar文件中有一个方法
Fuzzy.equals("jon","john");
它会在这种近似字符串中返回true。
答案 2 :(得分:1)
phonetic filter factory可以执行此操作。
搜索是solr的专长。并搜索类似的发声词。但是,如果您只是想要这个,并且不想要solr提供的其他功能,那么您可以使用可用的源here。
答案 3 :(得分:1)
估计 2个字符串的匹配
有很多理论和方法由于" jon"真的不等于" john",它很接近但不匹配
实施相当多的估算方法的一项伟大的学术工作被称为" SecondString.jar" - site link
大多数实施的方法都会给匹配一些分数,这个分数取决于使用的方法
实施例: 让我们定义"编辑距离"作为str1到str2所需的char更改次数 在这种情况下" jon" - > "约翰"需要添加1个字符 对于这种方法,自然会得分越低
答案 4 :(得分:1)
本文提供了有关基于Trie的Java近似字符串匹配实现的详细说明和完整代码: Fast and Easy Levenshtein distance using a Trie
def搜索(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
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 )