我目前正试图通过以下方案提出有效的问题解决方案:
给定一个输入字符串s和一个固定的词典,找到一个字符串w1 || w2(||表示连接,w1和w2是词典中的单词),与levenshtein的距离最小为s。
显而易见的天真解决方案是:
for word1 in lexicon:
for word2 in lexicon:
if lev_dist(word1 + word2) < lev_dist(lowest):
lowest = word1 + word2
我确信必须有更好的解决方案来解决这个问题。任何人都可以提供任何见解吗?
答案 0 :(得分:1)
您可以通过在单个字符串的成本上设置下限来做得更好。
查看http://en.wikipedia.org/wiki/Levenshtein_distance中的算法,在您关心计算d [i,j]的距离时,您知道要添加的贡献取决于s [i]和t [j],其中s和t是要比较的字符串,因此您可以使更改/删除/插入的成本取决于两个字符串中操作的位置。
这意味着您可以使用成本函数计算abcXXX和abcdef之间的距离,其中对标记为XXX的字符的操作是免费的。如果字符串XXX实际上是最有利的字符串,这允许您计算将abcXXX转换为abcdef的成本。
因此,对于词典中的每个单词w1,计算w1XXX与目标字符串和XXXw1与目标字符串之间的距离。制作两个词典副本,按w1XXX距离和XXXw1距离的顺序排序。现在按左手和右手成本之和的顺序尝试所有对,这是该对成本的下限。到目前为止,记录最佳答案。当最佳答案至少与您遇到的下一个下限成本一样好时,您知道您可以尝试的任何事情都可以改善这个最佳答案,因此您可以停止。
答案 1 :(得分:0)
我假设你想对同一个词典多次这样做。例如,您有一个拼写错误的单词并怀疑它是由于它们之间缺少空间而引起的。
您肯定需要的第一件事就是估算字符串&#34;亲密度&#34;。我喜欢标准化技术。例如,用等价类中的代表替换每个字母。 (也许M和N都会去M,因为它们听起来很相似。也许PH - > F出于类似的原因。)
现在,您希望您的规范化词典向前和向后进入特里或类似的结构。
现在,向前和向后搜索您的针,但要跟踪两个方向的中间结果。换句话说,在搜索字符串中的每个位置,跟踪已在该位置选择的候选特里节点列表。
现在,比较中间结果的前向和后向数组,寻找看起来像单词之间良好连接点的位置。您也可以逐个检查连接点。 (换句话说,你已经找到了第一个单词的结尾和第二个单词的开头。)
如果你这样做,那么你就找到了你的单词对。
答案 2 :(得分:0)
如果您在同一个词典上运行大量查询并希望改善查询时间,但可以花一些时间进行预处理,则可以创建一个包含w1 ||形式的所有可能单词的trie。 W2。然后,您可以使用此处描述的算法:Fast and Easy Levenshtein distance using a Trie来查找您需要的任何单词的答案。
算法的作用基本上是走在trie的节点上并跟踪当前的最小值。然后,如果你最终进入某个节点并且Levenshtein距离(从根到当前节点和输入字符串s的单词)已经大于到目前为止达到的最小值,你可以修剪以此节点为根的整个子树,因为它无法回答。
在我使用英语单词和随机查询单词的字典测试中,这比测试字典中每个单词的常规方法快30到300倍,具体取决于您在其上运行的查询类型。 / p>