Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 寻找相似字符串的优化方法_Algorithm_Search_Optimization - Fatal编程技术网

Algorithm 寻找相似字符串的优化方法

Algorithm 寻找相似字符串的优化方法,algorithm,search,optimization,Algorithm,Search,Optimization,假设我有一大堆单词。(大约4-5千人,而且还在增加)。有人在找一根绳子。很遗憾,在单词列表中找不到该字符串。现在,找到与输入字符串相似的单词的最佳优化方法是什么?我想到的第一件事是计算单词列表的每个条目和输入字符串之间的Levenshtein距离。但这是实现这一目标的最佳方式吗 (请注意,这不是特定于语言的问题)我认为有比这更好的东西存在,但BK树至少是蛮力的一个很好的优化 它使用了Levenshtein距离作为度量空间的属性,因此,如果您在查询和dict中的任意字符串s之间获得了d的Leven

假设我有一大堆单词。(大约4-5千人,而且还在增加)。有人在找一根绳子。很遗憾,在单词列表中找不到该字符串。现在,找到与输入字符串相似的单词的最佳优化方法是什么?我想到的第一件事是计算单词列表的每个条目和输入字符串之间的Levenshtein距离。但这是实现这一目标的最佳方式吗


(请注意,这不是特定于语言的问题)

我认为有比这更好的东西存在,但BK树至少是蛮力的一个很好的优化

它使用了Levenshtein距离作为度量空间的属性,因此,如果您在
查询
和dict中的任意字符串
s
之间获得了
d
的Levenshtein距离,那么您的所有结果必须在
(d+n)到(d-n)
s
之间。这里n是与要输出的查询的最大Levenshtein距离


这里有详细的解释:

如果您对代码本身感兴趣,我实现了一个算法来寻找两个字符串之间的最佳对齐方式。它基本上展示了如何通过
k
操作将一个字符串转换为另一个字符串(其中
k
是字符串的
Levenstein/编辑距离)。它可以根据您的需要稍微简化(因为您只需要距离本身)。顺便说一下,它在
O(mn)
中工作,其中
m
n
是字符串的长度。我的实现基于:和


这取决于更广泛的背景和你想要的准确程度。但我(可能)会从以下几点开始:

只考虑与查询词相同字符的子集。对于单个查询,它将减少约20个工作量
  • 我会根据单词的长度对它们进行分类,对于每个类别,允许最大距离是一个不同的数字。如果有4类,例如: 0——如果长度介于0和2之间;1——如果长度介于3和5之间;2——如果长度在6到8之间;3--如果长度为9+。然后根据查询长度,您可以只检查给定类别中的单词。此外,当超过
    最大距离时,执行停止算法应该不难
  • 如果需要,我们将开始考虑实施一些机器学习方法

  • 编辑:新解决方案

    是的,计算输入和单词列表之间的Levenshtein距离是一种合理的方法,但需要很多时间。BK树可以改善这一点,但随着Levenshtein距离的增大,它们会变得很慢。似乎我们可以使用trie加速Levenshtein距离计算,如这篇优秀的博文所述:

    它依赖于这样一个事实:Levenshtein距离的动态规划查找表在不同调用中有公共行,即
    Levenshtein(kate,cat)
    Levenshtein(kate,cat)

    使用字典运行该页面上给出的Python程序会给出:

    > python dict_lev.py HACKING 1
    Read 178691 words into 395185 nodes
    ('BACKING', 1)
    ('HACKING', 0)
    ('HACKLING', 1)
    ('HANKING', 1)
    ('HARKING', 1)
    ('HAWKING', 1)
    ('HOCKING', 1)
    ('JACKING', 1)
    ('LACKING', 1)
    ('PACKING', 1)
    ('SACKING', 1)
    ('SHACKING', 1)
    ('RACKING', 1)
    ('TACKING', 1)
    ('THACKING', 1)
    ('WHACKING', 1)
    ('YACKING', 1)
    Search took 0.0189998 s
    
    这真的很快,而且在其他语言中会更快。大部分时间都花在构建trie上,这与trie无关,因为它只需要执行一次并存储在内存中

    唯一的一个小缺点是,尝试占用大量内存(通过DAWG可以减少内存,但代价是一定的速度)

    另一种方法:彼得·诺维格(Peter Norvig)有一篇关于拼写纠正的伟大文章(包含完整的源代码)


    我们的想法是对单词进行可能的编辑,然后选择最有可能的单词拼写更正。

    听起来你大概想要一个自动拼写更正器-应该有很多关于这个的信息。@Dukeling,实际上,拼写更正器不是我想要的,但谢谢你。我现在可以搜索了:)@cipher如果你感兴趣的话,我刚刚发布了一个新的解决方案。@cipher好吧,网上有很多资料可供阅读。如果您有任何具体问题,请随时提问。
    > python dict_lev.py HACKING 1
    Read 178691 words into 395185 nodes
    ('BACKING', 1)
    ('HACKING', 0)
    ('HACKLING', 1)
    ('HANKING', 1)
    ('HARKING', 1)
    ('HAWKING', 1)
    ('HOCKING', 1)
    ('JACKING', 1)
    ('LACKING', 1)
    ('PACKING', 1)
    ('SACKING', 1)
    ('SHACKING', 1)
    ('RACKING', 1)
    ('TACKING', 1)
    ('THACKING', 1)
    ('WHACKING', 1)
    ('YACKING', 1)
    Search took 0.0189998 s