1、实践题目
编辑距离问题
2、问题描述
设A和B是2个字符串,对于给定的字符串A和字符串B,要用最少的字符操作(包括①删除一个字符;②插入一个字符;③将一个字符改为另一个字符)将字符串A转换为字符串B
而将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 计算A和B的编辑距离 d(A,B)
输入格式:第一行是字符串A,文件的第二行是字符串B,如:A字符串是:fxpimu,B字符串是:xwrs
输出格式:输出编辑距离 d(A,B),则上述样例的输出结果是:5
3、算法描述
(1)定义一个二维数组dist[m][n],表示处理字符串A的第m个字符和字符串B 的第n个字符后此时的已经完成的编辑距离d
(2)初始化数组dist,将其第一行和第一列初始化为1、2、3···m和1、2、3···n,表示当字符串B为空时或者字符串A为空时的编辑距离d。
(3)用i和j分别指向字符串A和B的单个字符
(4)删除、增加:dist[i][j-1]+1、dist[i-1][j]+1
(5)替换:首先判断字符串A的第i-1个,与字符串B的j-1个是否相同,如果相同,则dist[i-1][j-1]不变,否则dist[i-1][j-1]=dist[i-1][j-1]+1
(6)具体代码
1 import java.util.Scanner; 2 public class Main { 3 public static void main(String[] args) { 4 Scanner input = new Scanner(System.in); 5 String stringA = input.next(); 6 String stringB = input.next(); 7 int lengthA = stringA.length(); 8 int lengthB = stringB.length(); 9 int[][] dist = new int[lengthA+1][lengthB+1]; 10 for(int i=1;i<=lengthA;i++) { 11 dist[i][0] = i; 12 } 13 for(int j=1;j<=lengthB;j++) { 14 dist[0][j] = j; 15 } 16 for(int i=1;i<=lengthA;i++) { 17 for(int j=1;j<=lengthB;j++) { 18 if(stringA.charAt(i-1) == stringB.charAt(j-1)) { 19 dist[i-1][j-1] = dist[i-1][j-1]; 20 } 21 else { 22 dist[i-1][j-1] = dist[i-1][j-1]+1; 23 } 24 dist[i][j] = Math.min(Math.min(dist[i][j-1]+1,dist[i-1][j]+1),dist[i-1][j-1]); 25 } 26 } 27 System.out.println(dist[lengthA][lengthB]); 28 } 29 }
4、算法的时间和空间复杂度
时间复杂度:算法部分在双重循环中执行,第一重循环次数为n,第二重循环次数为m,故时间复杂度为O(n*m)
空间复杂度:由于定义了一个二维数组,故空间复杂度为O(n*m)
5、心得体会
一开始题目没怎么看懂,和队员一起分析了一会儿后大概地理解了题目,但是不知道应该如何用动态规划算法解决它,在网上查了一些资料,但也不是很懂他们的思路,最后请教了ACM大佬迪鸿同学,他很认真细致地给我们组讲解了这道题目的整个算法过程,让我们醍醐灌顶、受益匪浅,感谢大佬!