Edit Distance也称Levenshtein Distance,翻译为编辑距离算法,是一种计算两个字符串之间相似度的算法,主要解决的是一个字符串最少经过几次变换能得到另一个字符串。该算法可以用于information retrieval中的spelling correction问题。
该算法的本质是一个动态规划的问题。假设两个字符串如下:
string s:-------x
string t :----------y
i表示s的长度,j表示t的长度。dp[i][j]表示s转换成t的最少编辑次数。则dp[i-1][j-1]就表示s-'x'转换成t-'y'的最少编辑次数。
我们可以得出以下公式:
if x == y dp[i][j] = dp[i-1][j-1] 如果x与y相等,那么s转换成t的最少编辑次数就是s-'x'转换成t-'y'的最少编辑次数。
if x != y 如果x与y不相等,为了让s转换成t,我们可以对s执行以下三种操作:
插入y: dp[i][j] = dp[i][j-1]+1 该等式表示s转换成t的最少编辑次数等于s转换成t-'y'的最少编辑次数加上插入y(1次)
删除x: dp[i][j] = dp[i-1][j]+1 该等式表示s转换成t的最少编辑次数等于s先删除x(1次)加上s-'x'转换成t的最少编辑次数
用y替换x: dp[i][j] = dp[i-1][j-1]+1 该等式表示s转换成t的最少编辑次数等于s-'x'转换成t-'y'的最少编辑次数加上替换的次数(1次)
当x != y的时候 dp[i][j]就等于以上三种情况的最小值。
下面给出该算法的一种java实现:
class LevenshteinDistance{
public static void main(String[] args) {
String s = "cat";
String t = "dog";
int len = getLevenshteinDistance(s, t);
System.out.println(len);
}
public static int getLevenshteinDistance(String s, String t){
if(s == null || t == null)
throw new IllegalArgumentException("Strings must not be null");
if(s.equals(t))
return 0;
if(s.length() == 0)
return t.length();
if(t.length() == 0)
return s.length();
int m = s.length();
int n = t.length();
int [][] dp = new int[m+1][n+1];
for(int i=0; i<=m; i++)
dp[i][0] = i;
for(int j=0; j<=n; j++)
dp[0][j] = j;
for(int i=0; i<m; i++){
char c1 = s.charAt(i);
for(int j=0; j<n; j++){
char c2 = t.charAt(j);
if(c1 == c2)
dp[i+1][j+1] = dp[i][j];
else{
int replace = dp[i][j] + 1;
int insert = dp[i][j+1] + 1;
int delete = dp[i+1][j] + 1;
int min = replace > insert ? insert : replace;
min = delete > min ? min : delete;
dp[i + 1][j + 1] = min;
}
}
}
return dp[m][n];
}
}