显示Levenshtein Distance的结果

时间:2016-03-07 03:36:21

标签: levenshtein-distance

给定两个字符串(s1,s2),Levenshtein Distance是将s1更改为s2所需的最小操作数,反之亦然。

我想显示将s1更改为s2的结果。例如,将周日更改为周六需要3次操作。我需要展示S ++ u + day。 " +"适用于所需的每项操作。

1 个答案:

答案 0 :(得分:1)

这是一个返回您想要的javascript代码段。如果您熟悉dynamic programming algorithm,则应该可以遵循此代码。返回字符串r的所有字符串操作/操作以及min / curMin的处理都是从原始版本更改的。

function edits(t, s) {
    var r = "";
    if (s === t) {
        return s;
    }
    var n = s.length, m = t.length;
    if (n === 0 || m === 0) {
        return "+".repeat(n + m);
    }
    var x, y, a, b, c, min = 0;
    var p = new Array(n);
    for (y = 0; y < n;)
        p[y] = ++y;
    for (x = 0; x < m; x++) {
        var e = t.charCodeAt(x);
        c = x;
        b = x + 1;
        var currMin = min;
        min = n + 1;
        for (y = 0; y < n; y++) {
            a = p[y];
            if (a < c || b < c) {
                b = (a > b ? b + 1 : a + 1);
            }
            else {
                if (e !== s.charCodeAt(y)) {
                    b = c + 1;
                }
                else {
                    b = c;
                }
            }
            if (b < min) {
                min = b;
            }
            p[y] = b;
            c = a;
        }
        if (min > currMin) {
            r += "+";
        }
        else {
            r += t[x];
        }
    }
    return r;
}

编辑:上面的实现是针对速度和空间进行了优化的版本,因此可能更难阅读。下面的实现是JS version from Wikipedia的修改版本,应该更容易理解。

function getEditDistance(a, b) {
    if(a.length === 0) return "+".repeat(b.length);
    if(b.length === 0) return "+".repeat(a.length);

    var matrix = [];

    // increment along the first column of each row
    var i;
    for(i = 0; i <= b.length; i++){
        matrix[i] = [i];
    }

    // increment each column in the first row
    var j;
    for(j = 0; j <= a.length; j++){
        matrix[0][j] = j;
    }

    var r = "", min = 0;;

    // Fill in the rest of the matrix
    for(i = 1; i <= b.length; i++){

        var currMin = min;
        min = a.length + 1;

        for(j = 1; j <= a.length; j++){

            if(b.charAt(i-1) == a.charAt(j-1)){
                matrix[i][j] = matrix[i-1][j-1];
            } else {
                matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
                    Math.min(matrix[i][j-1] + 1, // insertion
                        matrix[i-1][j] + 1)); // deletion
            }

            if (matrix[i][j] < min) {
                min = matrix[i][j];
            }
        }

        if (min > currMin) {
            r += "+";
        }
        else {
            r += b[i-1];
        }
    }
    return r;
}

EDIT2:添加了算法和示例输出的说明

下面是输入字符串中的levenshtein矩阵&#34;小猫&#34;并且&#34;坐着&#34;。我在原始算法中改变的是,我添加了一个检查当前行的最小值是否大于前一行的最小值,如果是,则在当前行中进行编辑,从而添加&#34; +& #34 ;.如果不是和&#34;编辑费用&#34;对于当前行与前一行相同。然后没有必要编辑,我们只是将当前字符添加到结果字符串。您可以在图像中逐行跟踪算法(从第1行和第1列开始)

enter image description here

示例:

> getEditDistance("kitten", "sitting");
'+itt+n+'
> getEditDistance("Sunday", "Saturday");
'S++u+day'