我有一个包含50K至100K个字符串的字典(长度可达到50+个字符),我想找出给定的字符串是否在字典中,还要考虑一些“编辑”距离。例如Levenshtein距离。在搜索之前,我可以预先计算任何类型的数据结构。
我的目标是尽可能快地对那个字典运行成千上万的字符串,并返回最接近的邻居。如果有显着更快的算法来判断给定的字符串是否在字典中,则只需获得一个布尔值即可。
为此,我首先尝试计算所有的Levenshtein距离并取最小值,但这显然非常慢。因此,我尝试实现了基于本文 http://stevehanov.ca/blog/index.php?id=114 的Levenshtein Trie。
请查看我的 gist 进行重现基准测试: https://gist.github.com/nicolasmeunier/7493947 以下是我在我的机器上得到的一些基准测试结果: Edit distance of 0 (perfect match)
编辑距离为2时,速度会变得非常慢。
我的目标是尽可能快地对那个字典运行成千上万的字符串,并返回最接近的邻居。如果有显着更快的算法来判断给定的字符串是否在字典中,则只需获得一个布尔值即可。
为此,我首先尝试计算所有的Levenshtein距离并取最小值,但这显然非常慢。因此,我尝试实现了基于本文 http://stevehanov.ca/blog/index.php?id=114 的Levenshtein Trie。
请查看我的 gist 进行重现基准测试: https://gist.github.com/nicolasmeunier/7493947 以下是我在我的机器上得到的一些基准测试结果: Edit distance of 0 (perfect match)
Benchmark.measure { 10.times { dictionary.search(random_word, 0) } }
<Benchmark::Tms:0x007fa59bad8908 @label="", @real=0.010889, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.00999999999999801, @total=0.00999999999999801>
编辑距离为2时,速度会变得非常慢。
Benchmark.measure { 10.times { dictionary.search(random_word, 2) } }
<Benchmark::Tms:0x007fa58c9ca778 @label="", @real=3.404604, @cstime=0.0, @cutime=0.0, @stime=0.020000000000000018, @utime=3.3900000000000006, @total=3.4100000000000006>
从2次编辑距离开始,速度会急剧下降(每个测试字符串平均需要1秒以上)。
我想知道如何/是否可以显着加快这个过程。如果已经在ruby/gems中实现了现有的解决方案,我也不想重复造轮子...
编辑1:在我的情况下,我希望大多数我匹配字典的字符串不在其中。因此,如果有任何算法可以快速丢弃一个字符串,那确实可以帮上大忙。
谢谢, Nicolas