编辑距离是什么?下面是摘自维基百科的说明:
莱文斯坦距离,又称Levenshtein距离,是编辑距离(edit distance)的一种。指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将kitten一字转成sitting:
俄罗斯科学家弗拉基米尔·莱文斯坦在1965年提出这个概念。
从一个字符串变到另一个字符串可以:
从 hello 变到 aeliloo:
所以编辑距离为:3
首先定义两个变量 i(目标字符串中字符的位置)和 j(原始字符串中字符的位置)
则编辑距离 s = D(i,j)
最小编辑距离算法伪代码:
function MinEditDistance(targetStr, sourceStr) {
n = length(targetStr)
m = length(sourceStr)
matrix D[n,m]
D[0,0] = 0;
D[0,1] = 1......D[0,m] = m;
D[1,0] = 1......D[n,0] = n;
for i of range: 1 to n
for j of range: 1 to m
D[i, j] = min(D[i-1, j] + 1, D[i, j-1] + 1, D[i-1, j-1] + f(i, j))
return D[n,m]
}
从 hello 变到 aeliloo:目标字符串 aeliloo,源字符串 hello
由:
D[0,0] = 0;
D[0,1] = 1......D[0,m] = m;
D[1,0] = 1......D[n,0] = n;
可得 dMatrix:
0 | 1,a | 2,e | 3,l | 4,i | 5,l | 6,o | 7,o |
---|---|---|---|---|---|---|---|
1,h | |||||||
2,e | |||||||
3,l | |||||||
4,l | |||||||
5,o |
由: dMatrix[i,j] = min(dMatrix[i-1, j] + 1, dMatrix[i, j-1] + 1, dMatrix[i-1, j-1] + f(i, j))
当: i = 1, j = 1
所以:dMatrix[1,1] = min(dMatrix[0, 1] + 1, dMatrix[1, 0] + 1, dMatrix[0, 0] + f(1, 1)) 由于 字符 a
不等于 h
所以 f(1,1) = 1
得:dMatrix[1,1] = 1;
0 | 1,a | 2,e | 3,l | 4,i | 5,l | 6,o | 7,o |
---|---|---|---|---|---|---|---|
1,h | 1 | ||||||
2,e | |||||||
3,l | |||||||
4,l | |||||||
5,o |
由此可以得到最终 dMatrix:
0 | 1,a | 2,e | 3,l | 4,i | 5,l | 6,o | 7,o |
---|---|---|---|---|---|---|---|
1,h | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
2,e | 2 | 1 | 2 | 3 | 4 | 5 | 6 |
3,l | 3 | 2 | 1 | 2 | 3 | 4 | 5 |
4,l | 4 | 3 | 2 | 2 | 2 | 3 | 4 |
5,o | 5 | 4 | 3 | 3 | 3 | 2 | 3 |
最小编辑距离 s = dMatrix[7, 5] = 3
'use strict';
function minEditDistance(target, source) {
var tLen, sLen, dMatrix, i, j, temp;
tLen = target.length;
sLen = source.length;
dMatrix = [];
for(i = 0; i <= tLen; i++) {
dMatrix.push([i]);
}
for(i = 0; i <= sLen; i++) {
dMatrix[0][i] = i;
}
for(i = 1; i <= tLen; i++) {
for(j = 1; j <= sLen; j++) {
temp = [];
temp.push(dMatrix[i][j-1] + 1);
temp.push(dMatrix[i-1][j] + 1);
temp.push(dMatrix[i-1][j-1] + (target[i - 1] === source[j - 1] ? 0 : 1));
dMatrix[i][j] = Math.min.apply(null, temp);
}
}
return dMatrix[tLen][sLen];
}