首页 > 解决方案 > 最佳对齐的字符串相似度

问题描述

算法的预期行为

我有两个字符串ab并且a是较短的字符串。我想找到与b具有最大相似性的子字符串a。子字符串必须是 of len(a),或者必须放在 的末尾b。例如对于以下两个字符串:

a = "aa"
b = "bbaba"

b 的可能子串是

"bb"
"ba"
"ab"
"ba"
"a"
""

编辑距离定义为插入和删除的数量。替换是不可能的(必须使用插入+删除代替)。两个字符串之间的相似度根据以下等式计算:norm = 1 - distance / (len(a) + len(substring)). 因此,上面的子字符串将提供以下结果:

"bb" -> 2 DEL + 2 INS -> 1 - 4 / 4 = 0
"ba" -> 1 DEL + 1 INS -> 1 - 2 / 4 = 0.5
"ab" -> 1 DEL + 1 INS -> 1 - 2 / 4 = 0.5
"ba" -> 1 DEL + 1 INS -> 1 - 2 / 4 = 0.5
"a"  ->         1 INS -> 1 - 1 / 3 = 0.66
""   ->         2 INS -> 1 - 2 / 2 = 0

所以算法应该返回 0.66。

不同的实现

Python 库 FuzzyWuzzy 以fuzz.partial_ratio. 它分两步计算比率:

  1. 使用 difflib.SequenceMatcher.get_matching_blocks 在较长序列中搜索匹配的子序列

  2. 从匹配的子序列开始计算 len(shorter_string) 的子字符串的比率并返回最大比率

这真的很慢,所以它在可用时使用 python-Levenshtein 进行这种相似度计算。这会根据 Levenshtein 距离执行相同的计算,但速度更快。然而,在边缘情况下,用于比率计算的匹配块是完全错误的(参见问题 16),当正确性相关时,这不会使其成为合适的替代品。

当前实施

我目前使用 difflib 的 C++ 端口与 Levenshtein 距离的快速位并行实现相结合,权重插入 = 1、删除 = 1 和替换 = 2。当前的实现可以在这里找到:

问题

有没有更快的算法来计算这种相似度。要求是:

标签: algorithmlevenshtein-distanceedit-distancesequence-alignment

解决方案


推荐阅读