【发布时间】:2010-08-23 20:29:52
【问题描述】:
我想知道是否有一个库可以告诉我两个字符串的相似程度
我不是在寻找任何具体的东西,但在这种情况下:
a = 'alex is a buff dude'
b = 'a;exx is a buff dud'
我们可以说b 和a 的相似度约为 90%。
有没有图书馆可以做到这一点?
【问题讨论】:
-
Text difference algorithm 的可能重复项
我想知道是否有一个库可以告诉我两个字符串的相似程度
我不是在寻找任何具体的东西,但在这种情况下:
a = 'alex is a buff dude'
b = 'a;exx is a buff dud'
我们可以说b 和a 的相似度约为 90%。
有没有图书馆可以做到这一点?
【问题讨论】:
import difflib
>>> a = 'alex is a buff dude'
>>> b = 'a;exx is a buff dud'
>>> difflib.SequenceMatcher(None, a, b).ratio()
0.89473684210526316
【讨论】:
http://en.wikipedia.org/wiki/Levenshtein_distance
pypi 上有一些库,但请注意,这很昂贵,尤其是对于较长的字符串。
您可能还想查看 python 的 difflib:http://docs.python.org/library/difflib.html
【讨论】:
寻找Levenshtein 比较字符串的算法。这是通过 google 找到的随机实现:http://hetland.org/coding/python/levenshtein.py
【讨论】:
另一种方法是使用最长公共子串。这里是我的 lcs 实现在 Daniweb 中的实现(这也在 difflib 中定义)
这里是简单的长度版本,以列表作为数据结构:
def longest_common_sequence(a,b):
n1=len(a)
n2=len(b)
previous=[]
for i in range(n2):
previous.append(0)
over = 0
for ch1 in a:
left = corner = 0
for ch2 in b:
over = previous.pop(0)
if ch1 == ch2:
this = corner + 1
else:
this = over if over >= left else left
previous.append(this)
left, corner = this, over
return 200.0*previous.pop()/(n1+n2)
这是我的第二个 version which actualy gives the common string 使用双端队列数据结构(也带有示例数据用例):
from collections import deque
a = 'alex is a buff dude'
b = 'a;exx is a buff dud'
def lcs_tuple(a,b):
n1=len(a)
n2=len(b)
previous=deque()
for i in range(n2):
previous.append((0,''))
over = (0,'')
for i in range(n1):
left = corner = (0,'')
for j in range(n2):
over = previous.popleft()
if a[i] == b[j]:
this = corner[0] + 1, corner[1]+a[i]
else:
this = max(over,left)
previous.append(this)
left, corner = this, over
return 200.0*this[0]/(n1+n2),this[1]
print lcs_tuple(a,b)
""" Output:
(89.47368421052632, 'aex is a buff dud')
"""
【讨论】: