2010-08-23 63 views
10

Tôi muốn biết nếu có một thư viện mà sẽ cho tôi biết khoảng cách tương tự như hai chuỗi làpython: so sánh hai chuỗi

Tôi không tìm kiếm bất cứ điều gì cụ thể, nhưng trong trường hợp này:

a = 'alex is a buff dude' 
b = 'a;exx is a buff dud' 

chúng tôi có thể nói rằng ba tương đương khoảng 90%.

Có thư viện nào có thể thực hiện việc này không?

+0

thể trùng lặp của [thuật toán chênh lệch Text] (http://stackoverflow.com/questions/145607/text-difference-algorithm) – tzot

Trả lời

16
import difflib 

>>> a = 'alex is a buff dude' 
>>> b = 'a;exx is a buff dud' 
>>> difflib.SequenceMatcher(None, a, b).ratio() 

0.89473684210526316 
6

http://en.wikipedia.org/wiki/Levenshtein_distance

Có một vài thư viện trên , nhưng lưu ý rằng đây là tốn kém, đặc biệt là cho các chuỗi dài hơn.

Bạn cũng có thể muốn kiểm tra difflib python của: http://docs.python.org/library/difflib.html

+0

đắt tiền? difflib là một quái vật so với việc triển khai Levenshtein bán phong nha. –

+0

Nó không phải là ý định của tôi để đề nghị rằng difflib là ít tốn kém - nó chỉ làm tương tự, mặc dù một chút khác nhau, điều. –

1

cách khác là sử dụng chuỗi con chung dài nhất. Dưới đây là một thực hiện trong Daniweb với thực hiện LCS của tôi (điều này cũng được định nghĩa trong difflib)

Đây là đơn giản chỉ chiều dài phiên bản với danh sách như cấu trúc dữ liệu:

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) 

Đây là của tôi thứ hai version which actualy gives the common string với cấu trúc dữ liệu deque (còn với các trường hợp sử dụng dữ liệu chẳng hạn):

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') 
"""