如何在1的距离内找到字典中的字符串变体?

时间:2019-02-11 09:44:05

标签: python string levenshtein-distance

假设您已扫描带有名称的文档。由于扫描过程中的错误,您想在词典中查找名称。因此,您需要一个函数,该函数接受一个可能的名称并输出一个列表,该列表的输入的所有可能的字符串变化都应在Levenshtein-Distance为1的范围内。

我修改了一个实现(https://rosettacode.org/wiki/Levenshtein_distance#Python),但没有得到正确的结果。由于Levenshtein的实现通常会接受两个字符串并进行比较以给出L距离的整数,所以我想知道如何更改它以获取一个字符串的变体吗?

def levenshteinVariation(n_possible):


m = n_possible
n = n_correct

d = []           

for i in range(len(m)+1):
    d.append([i])        
del d[0][0]    

for j in range(len(n)+1):
    d[0].append(j)       

for j in range(1,len(n)+1):

    for i in range(1,len(m)+1):

        if m[i-1] == n[j-1]:
            d[i].insert(j,d[i-1][j-1])           

        else:
            minimum = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+2)         
            d[i].insert(j, minimum)

return d 

预期结果将是字典中L距离为1内的所有变体的匹配。

for n_correct, n_possible in [('Marcus','Maacus'), ('David','Davide'), ('Steve', 'Steven')]:
print(f"{n_correct} found: {n_correct in levenshteinVariation(n_possible)}")

但是我得到了

Marcus found: False
David found: False
Steve found: False

1 个答案:

答案 0 :(得分:0)

感谢DanD。我能够自己解决它:

def Variations1(name):

letters    = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

splits     = [(name[:i], name[i:])    for i in range(len(name) + 1)]
deletes    = [L + R[1:]               for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1]
replaces   = [L + c + R[1:]           for L, R in splits if R for c in letters]
inserts    = [L + c + R               for L, R in splits for c in letters]

return set(deletes + transposes + replaces + inserts)