2012-06-13 75 views
2

找到位置,我有兩個很長的單詞序列。其中兩個字符串不同

我需要找到它們的不同地方。例如,如果輸入的是

1st sequence: A B C D E F G 
2nd sequence: A X D Y Z W G 

(每個字符在這裏表示一個字)

輸出應該是:

B C -> X 
E F -> Y Z W 

我所想的:我能有一個索引兩個序列。最初,兩者都會指向A.增加兩個指數。現在,第一指標點到B,第二爲X.我現在可以搜索B.沒有找到它的整個第二序列,我可以搜索C中的整個第二序列,然後D.我會找到一個d,和可以因此解決問題。

顯然,這種「蠻力」的方法是可怕的。

什麼是更好的方法?

我寫我的Python代碼,並使用NLTK,因此,如果這可以部分或完全使用內置NLTK功能來解決,這將是更快(實施)。

+0

最長公共子可能更適用。 –

回答

7

difflib . SequenceMatcher . get_opcodes可以做到這一點。

import difflib 

def diff(a, b): 
    for tag, i1, i2, j1, j2 in difflib.SequenceMatcher(a=a, b=b).get_opcodes(): 
     if tag!='equal': 
      yield a[i1:i2], b[j1:j2] 

>>> d = list(diff('A B C D E F G'.split(), 'A X D Y Z W G'.split())) 
>>> d 
[(['B', 'C'], ['X']), (['E', 'F'], ['Y', 'Z', 'W'])] 
>>> '\n'.join('{} -> {}'.format(*(' '.join(i) for i in l)) for l in d) 
B C -> X 
E F -> Y Z W 

老答案–等效功能:

import difflib 

def diff(a, b): 
    add, remove = [], [] 
    for line in difflib.ndiff(a, b): 
     d, line = line[0], line[2:] 
     if d in '+-': 
      (add if d=='+' else remove).append(line) 
     elif add or remove: 
      yield remove, add 
      add, remove = [], [] 
    if add or remove: 
     yield remove, add 
+0

這無疑解決了這個問題!謝謝!如果我需要找出difflib在內部使用的算法,我會查找他們的文檔。 –

1

這是經典的編輯距離問題。我只是想讓你谷歌它,並瞭解它是如何工作的。沒有必要在這一個代表。

+0

NLTK具有以下功能:找到編輯距離。問題是 - 這只是兩個字符串之間相似性的數字度量。我剛剛在我的兩個'測試'字符串之間獲得了34的Levenstein距離。但是,我需要實際的差異和他們的位置,而不僅僅是一個數字! –

+0

您可以輕鬆地修改編輯距離的問題,給你,你必須做出的實際變化。 – sukunrt

相關問題