计算两段文本之间百分比差异的算法
我一直在研究如何找到一个高效的解决方案。我查阅了一些比较差异的工具,比如谷歌的 diff-match-patch 和 Python 的 diff,还有一些最长公共链的算法。
我希望能听听你们的建议,看看有什么方法可以解决这个问题。有没有特别推荐的算法或库呢?
4 个回答
1
最长公共链?也许这个链接对你有帮助:http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
2
除了 difflib
和其他常见的子序列库,如果你处理的是自然语言文本,可以考虑使用词干提取(stemming),这是一种把单词归一化到其根本形式的方法。你可以在自然语言工具包(Natural Language Toolkit,简称NLTK)中找到几种实现方式,网址是 http://www.nltk.org/。另外,你还可以通过使用N-Grams(http://en.wikipedia.org/wiki/N-gram)来更语义化地比较自然语言文本。
6
我不太明白“最长公共[[链?子串?]]”和“百分比差异”有什么关系,尤其是在看到评论中提到你期望两个字符串之间的差异非常小,而这两个字符串中间只有一个字符不同(所以它们的最长公共子串大约是字符串长度的一半)之后。
抛开“最长公共”的奇怪说法,我们可以把“百分比差异”定义为两个字符串之间的编辑距离除以最大长度(当然要乘以100;-),那么这样说怎么样:
def levenshtein_distance(first, second):
"""Find the Levenshtein distance between two strings."""
if len(first) > len(second):
first, second = second, first
if len(second) == 0:
return len(first)
first_length = len(first) + 1
second_length = len(second) + 1
distance_matrix = [[0] * second_length for x in range(first_length)]
for i in range(first_length):
distance_matrix[i][0] = i
for j in range(second_length):
distance_matrix[0][j]=j
for i in xrange(1, first_length):
for j in range(1, second_length):
deletion = distance_matrix[i-1][j] + 1
insertion = distance_matrix[i][j-1] + 1
substitution = distance_matrix[i-1][j-1]
if first[i-1] != second[j-1]:
substitution += 1
distance_matrix[i][j] = min(insertion, deletion, substitution)
return distance_matrix[first_length-1][second_length-1]
def percent_diff(first, second):
return 100*levenshtein_distance(a, b) / float(max(len(a), len(b)))
a = "the quick brown fox"
b = "the quick vrown fox"
print '%.2f' % percent_diff(a, b)
Levenshtein函数来自于Stavros的博客。在这种情况下,结果将是5.26(百分比差异)。