我有两个非常长的单词序列。
我需要找到不同的地方例如,如果输入是
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功能部分或完全解决此问题,则会更快(实现)。
最佳答案
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