定义
编辑距离是字符串之间的一种距离度量,也称为Levenshtein距离;这种距离的含义是:通过最少的操作把一个字符串变换成另外一个字符串。 一次操作包括:删除、插入和替换一个字符。
编辑距离越小,代表越相似。
例子
将kitten转换成sitting的步骤:
1. kitten->sitten(替换k->s)
2. sitten->sittin(替换e->i)
3. sittin->sitting(插入g)
编辑距离为3.
问题定义
编辑距离的定义(最小的操作次数)。
假设设为字符串
a,b
a
,
b
, 那么我们设
lev(i,j)
l
e
v
(
i
,
j
)
代表 a[0,i] a [ 0 , i ] 和 b[0,j] b [ 0 , j ] 之间的编辑距离;那么我们的目标则是求:
lev(m,n) l e v ( m , n ) , 其中: m=|a|,n=|b| m = | a | , n = | b |
问题求解
lev(i,j)=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪i,j,min⎧⎩⎨lev(i−1,j)+1lev(i,j−1)+1,lev(i−1,j−1)+1,if (ai!=bj)if j==0if i==0(迭代公式)
(迭代公式)
l
e
v
(
i
,
j
)
=
{
i
,
if
j
==
0
j
,
if
i
==
0
m
i
n
{
l
e
v
(
i
−
1
,
j
)
+
1
l
e
v
(
i
,
j
−
1
)
+
1
,
l
e
v
(
i
−
1
,
j
−
1
)
+
1
,
if
(
a
i
!
=
b
j
)
有了这个迭代公式,问题的求解则迎刃而解。
迭代公式或者更新公式,则是大多数数值问题的求解思路,比如随机梯度下降的W更新公式等。
代码实现
private static int min(int... is) {
int min = Integer.MAX_VALUE;
for (int i : is) {
if (min > i) {
min = i;
}
}
return min;
}
public int minDistance(String str1, String str2) {
int len1 = str1.length();
int len2 = str2.length();
//初始化
int[][] lev = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i++) {
lev[i][0] = i;
}
for (int j = 0; j <= len2; j++) {
lev[0][j] = j;
}
int temp;
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
temp = 0;
} else {
temp = 1;
}
lev[i][j] = min(lev[i - 1][j - 1] + temp, //替换代价
lev[i][j - 1] + 1,
lev[i - 1][j] + 1);
}
}
return lev[len1][len2];
}
leetcode的例子:https://leetcode.com/problems/edit-distance/description/