【算法设计与分析】编辑距离问题(动态规划)

问题描述:已知两个字符串word1word2,求从word1转化成word2最少需要几步。

其中,每一步只能进行以下三个操作之一:

  1. 插入一个字符
  2. 删除一个字符
  3. 替换一个字符

用动态规划的思路,用dp[i][j]表示word1的前i个字符转化为word2的前j个字符需要的操作次数。

根据word1word2的最后一个字符是否相同,分为两种情况:

1、word1[i] == word2[j]:那么同时去掉最后一个字符,不影响结果,故dp[i][j] = dp[i-1][j-1]

2、word1[i] != word2[j]:可以用如下三种方法进行操作:

将word1转化为word2的前j-1个字符,再将word2的最后一个字符插入到word1末尾。即步骤为dp[i][j-1]+1

将word1的前i-1个字符转化为word2,再将word1的最后一个字符删除。即步骤为dp[i-1][j]+1

将word1的前i-1个字符转化为word2的前j-1个字符,再将word1的第i个字符替换为word2的第j个字符,即步骤为dp[i-1][j-1]+1
dp[i][j]为三种方法的最小值,即dp[i][j] = min(dp[i][j-1]+1, dp[i-1][j]+1, dp[i-1][j-1]+1)。

public class MinDistance {
	
	public static int Min(String s1,String s2){
		int m = s1.length();
		int n = s2.length();
		int[][] dp = new int[m+1][n+1];
		for(int i = 1;i <= m;i++){
			dp[i][0] = i;
		}
		for(int i = 1;i <= n;i++){
			dp[0][i] = i;
		}
		// 自底向上求解
		for(int i = 1;i <= m;i++){
			for(int j = 1;j <= n;j++){
				if(s1.charAt(i-1) == s2.charAt(j-1)){
					dp[i][j] = dp[i-1][j-1]; // 对应相等,直接跳过
				}else{
					//dp[i-1][j]+1  删除操作
					//dp[i][j-1]+1  插入操作
					//dp[i-1][j-1]+1 替换操作
					dp[i][j] = Math.min
                                  (dp[i-1][j]+1, Math.min(dp[i][j-1]+1, dp[i-1][j-1]+1));
				}
			}
		}
		// 储存最小值
		return dp[m][n];
	}
	
	public static void main(String[] args) {
		String s1 = "rad";
		String s2 = "apple";
		int min = Min(s1, s2);
		System.out.println(min);
	}
}

你可能感兴趣的:(算法设计与分析)