分别计算Levenshtein距离算法中的删除次数

时间:2014-10-10 08:20:22

标签: ruby algorithm levenshtein-distance edit-distance

所以我意识到Levenshtein距离算法考虑了将字符串A更改为字符串B所需的最小删除次数,插入次数和替换次数。但是,我想知道如何分别跟踪数字删除操作所需的总编辑内容。我正在研究这种算法的实现,

def levenshtein(first, second)
    first = first.split
    second = second.split
    first_size = first.size
    second_size = second.size
    matrix = [(0..first_size).to_a]
    (1..second_size ).each do |j|
        matrix << [j] + [0] * (first_size)
    end
    count = 0
    (1..second_size).each do |i|
       (1..first_size).each do |j|
         if first[j-1] == second[i-1]
           matrix[i][j] = matrix[i-1][j-1]
         else
           matrix[i][j] = [matrix[i-1][j],matrix[i][j-1], matrix[i-1][j-1]].min + 1
         end
       end
    end
    return matrix.last.last 
end

因此,为了跟踪删除,我尝试了:

if matrix[i-1[j] == [matrix[i-1][j],matrix[i][j-1], matrix[i-1][j-1]].min
然后增加计数。但是,这似乎不起作用。我也尝试在两个字符串中获得大小差异,但在以下情况下失败

String 1: "my response to prompt#1"
String 2: "my edited response to"

这里显然有1个删除,但只是获得大小差异不会检测到。

我想知道是否有人知道如何跟踪将字符串A更改为字符串B的总编辑中涉及的删除次数。

1 个答案:

答案 0 :(得分:3)

通过使表格的每个条目成为由两个数量组成的列表,我们可以使删除计数与替换次数一起进行。 (作为副作用,次要优化目标是最小化删除次数。我不知道这是否可取。)

def levenshtein(first, second)
    first = first.split
    second = second.split
    first_size = first.size
    second_size = second.size
    matrix = [(0..first_size).to_a]
    (1..second_size ).each do |j|
        matrix << [[j,0]] + [[0,0]] * (first_size)
    end
    count = 0
    (1..second_size).each do |i|
       (1..first_size).each do |j|
         if first[j-1] == second[i-1]
           matrix[i][j] = matrix[i-1][j-1]
         else
           matrix[i][j] = [[matrix[i-1][j  ][0]+1, matrix[i-1][j  ][1]  ],
                           [matrix[i  ][j-1][0]+1, matrix[i  ][j-1][1]+1],
                           [matrix[i-1][j-1][0]+1, matrix[i-1][j-1][1]  ]].min
         end
       end
    end
    return matrix.last.last 
end