【题目6】编辑距离
可以对一个字符串进行三种操作:插入一个字符、删除一个字符、替换一个字符
给定2个字符串s1和s2,计算将s1转换为s2最少需要多少次操作,并打印出具体操作。
【举例】
s1 = "intention",s2 = "execution",输出:
Change s1=intention to s2=execution:
s1[8]:skip 'n'
s1[7]:skip 'o'
s1[6]:skip 'i'
s1[5]:skip 't'
s1[4]:insert 'u'
s1[4]:replace 'n'with 'c'
s1[3]:skip 'e'
s1[2]:delete 't'
s1[1]:replace 'n'with 'x'
s1[0]:replace 'i'with 'e'
5
public class Code06_MinDistance { public static class Node { public int val; public int choice;// 0代表啥都不做,1代表插入,2代表删除,3代表替换 public Node(int val, int choice) { this.val = val; this.choice = choice; } } public static int minDistance(String s1, String s2) { int m = s1.length(); int n = s2.length(); // dp[i][j]--s1[0...i-1]和s2[0...j-1]的最小编辑距离 Node[][] dp = new Node[m + 1][n + 1]; dp[0][0] = new Node(0, 0);// 别忘记初始化dp[0][0],否则会报空指针使用问题!!!!!!! for (int i = 1; i <= m; i++) { dp[i][0] = new Node(i, 2); } for (int i = 1; i <= n; i++) { dp[0][i] = new Node(i, 1); } // dp[i - 1][j]#删除-2dp[i][j - 1]#插入1-dp[i - 1][j - 1]#替换3 for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (s1.charAt(i - 1) == s2.charAt(j - 1)) {// 这里没用转换成char数组 Node node = dp[i - 1][j - 1]; dp[i][j] = new Node(node.val, 0); } else { dp[i][j] = minNode(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]); dp[i][j].val++; } } } printResult(dp, s1, s2); return dp[m][n].val; } private static void printResult(Node[][] dp, String s1, String s2) { int rows = dp.length; int cols = dp[0].length; int i = rows - 1, j = cols - 1; System.out.println("Change s1=" + s1 + " to s2=" + s2 + ":\n"); while (i != 0 && j != 0) { char c1 = s1.charAt(i - 1); char c2 = s2.charAt(j - 1); int choice = dp[i][j].choice; System.out.print("s1[" + (i - 1) + "]:"); switch (choice) { case 0: System.out.println("skip '" + c1 + "'"); i--; j--; break; case 1: System.out.println("insert '" + c2 + "'"); j--; break; case 2: System.out.println("delete '" + c1 + "'"); i--; break; case 3: System.out.println("replace '" + c1 + "'" + "with '" + c2 + "'"); i--; j--; break; } } while (i > 0) { System.out.print("s1[" + (i - 1) + "]:"); System.out.println("delete '" + s1.charAt(i - 1) + "'"); i--; } while (j > 0) { System.out.print("s1[0]:"); System.out.println("insert '" + s2.charAt(j - 1) + "'"); j--; } } private static Node minNode(Node a, Node b, Node c) { Node res = new Node(a.val, 2); if (res.val > b.val) { res.val = b.val; res.choice = 1; } if (res.val > c.val) { res.val = c.val; res.choice = 3; } return res; } public static void main(String[] args) { String s1 = "intention"; String s2 = "execution"; System.out.println(minDistance(s1, s2)); } }