Levenshtein距离或其派生算法是您想要的算法。
将给定字符串与字典中的每个字符串进行匹配。
(如果您只需要固定数量的最相似字符串,则可以使用min-heap。)
如果运行字典中所有字符串的Levenshtein距离太昂贵,则首先使用一些粗略的算法,从候选列表中排除距离太远的单词。
之后,在剩余的候选单词上运行Levenshtein距离。
一种排除距离较远的单词的方法是索引n-gram。
通过将每个单词拆分成n-gram列表来预处理字典。
例如,考虑n=3:
(0) "Hello world" -> ["Hel", "ell", "llo", "lo ", "o w", " wo", "wor", "orl", "rld"]
(1) "FooBarbar" -> ["Foo", "ooB", "oBa", "Bar", "arb", "rba", "bar"]
(2) "Foo world!" -> ["Foo", "oo ", "o w", " wo", "wor", "orl", "rld", "ld!"]
接下来,创建n元索引:
" wo" -> [0, 2]
"Bar" -> [1]
"Foo" -> [1, 2]
"Hel" -> [0]
"arb" -> [1]
"bar" -> [1]
"ell" -> [0]
"ld!" -> [2]
"llo" -> [0]
"lo " -> [0]
"o w" -> [0, 2]
"oBa" -> [1]
"oo " -> [2]
"ooB" -> [1]
"orl" -> [0, 2]
"rba" -> [1]
"rld" -> [0, 2]
"wor" -> [0, 2]
当您需要查找与给定字符串最相似的字符串时,您可以将给定字符串拆分为n-gram,并仅选择那些从字典中至少具有一个匹配的n-gram的单词。
这样可以将候选项数量减少到合理的数量,并且您可以继续使用Levenshtein算法将给定字符串与剩余候选项中的每个字符串进行匹配。
如果您的字符串足够长,则可以通过使用min-hashing技术来减少索引大小:对于每个n-gram,您计算普通哈希,并仅使用K个最小哈希,其他哈希则被丢弃。
P.S. 这个演示文稿似乎是解决您问题的良好入门介绍。