题目
给定2个字符串,str1,str2,求这两个字符串的最小Edit Distance;
Edit Distance:用于衡量两个strings之间的相似性。
两个strings之间的Minimum edit distance是指把其中一个string通过编辑(包括插入,删除,替换操作)转换为另一个string的最小操作数。
分析
那么如何找到两个strings的minimun edit distance呢?要知道把一个string转换为另一个string可以有很多种方法(或者说“路径“)。我们所知道起始状态(第一个string)、终止状态(另一个string)、基本操作(插入、删除、替换),要求的是最短路径。
对于如下两个strings:
X的长度为n
Y的长度为m
我们定义D(i,j)为 X 的前i个字符 X[1…i] 与 Y 的前j个字符 Y[1…j] 之间的距离,其中0<i<n, 0<j<m,
因此X与Y的距离可以用D(n,m)来表示。
假如我们想要计算最终的D(n,m),那么可以从头开始,先计算D(i, j) (i和j从1开始)的值,然后基于前面的结果计算更大的D(i, j),直到最终求得D(n,m)。
递推公式:
dp[i][j]=min{
dp[i-1][j]+1
dp[i][j-1]+1;
dp[i-1][j-1]+0 if(X[i]==X[j]
+1 if 不等
}
初始化
dp[i][0]=i
dp[0][j]=j
实现
public static int minDistance(String word1, String word2) {
int m=word1.length();
int n=word2.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=1;i<=m;i++){
for(int j=1;j<=n;j++){
int min=Math.min(dp[i-1][j]+1, dp[i][j-1]+1);
if(word1.charAt(i-1)==word2.charAt(j-1)){
min=Math.min(min, dp[i-1][j-1]);
}else{
min=Math.min(min, dp[i-1][j-1]+1);
}
dp[i][j]=min;
}
}
return dp[m][n];
}