查找两个字符串不同的位置

时间:2012-06-13 10:43:25

标签: python string algorithm pattern-matching nltk

我有两个非常长的单词序列。

我需要找到他们不同的地方。例如,如果输入是

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功能部分或完全解决这个问题,那么(实现)会更快。

3 个答案:

答案 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

答案 1 :(得分:1)

这是经典的编辑距离问题。我只是想让你谷歌并了解它是如何工作的。不需要这个代表。

答案 2 :(得分:0)

查看Levenstein distance wikipedia page上的伪代码示例。可以轻松修改此示例以满足您的需求。