算法·实验报告2
主题:动态规划
时间:2019/10/16
1、实践题目
7-3 编辑距离问题 (30 分)
设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。
这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。
将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。
对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。
此题目并不要求求变换序列过程,只是计算。
2、问题描述
此问题可以和最短路类比:每一次选择看似无法选择:因为不知道该i次选择是不是能导致n-i也是最优选择。
同样,从后往前在某个位置修改删除插入元素是不是能导致前面的元素的编辑距离最小。
但他们都有一个相同的特征,从第一个初始状态往后分析,(递归是从最后一个状态往前分析)第k个状态只和第k-1个状态有关。
步骤1:写出递归公式
a\b数组下标从1开始
if(a[i]==b[j]) arr[i][j]=arr[i-1][j-1]; else{ arr[i][j]=arr[i-1][j]+1;//删除a[i] arr[i][j]=arr[i][j-1]+1;//删除b[j] arr[i][j]=arr[i-1][j-1]+1;//修改a[i]/b[j] arr[i][j]=arr[i][j-1]+1;//在a[i]后面插入b[j] arr[i][j]=arr[i-1][j]+1;//在b[j]后面插入a[i] }
这里可能会有两种担忧:
1、当i/j=1时 i-1/j-1越界
2、当一个数组为空时
分析:
实际上以上两种担忧可以通过初始化一行+一列arr[i][o]arr[0][j]
假设arr[1][1]-删除b[1]--arr[1][1]=arr[1][0]+1
由于a数组剩余i个b数组有0个,那么arr[1][0]需要做的操作则为i个
因此解决的方法是从i和j分别从1开始遍历,并初始化以下
void setArr(int n1,int n2){ arr[0][0] = 0; for(int i = 1; i<=n1;i++){ arr[i][0] = i; } for(int j = 1; j<=n2;j++){ arr[0][j] = j; } }
3、算法时间空间复杂度
时间复杂度:O(n²)
分析:for循环中i/j两层 n1*n2
空间复杂度:O(n²)
分析:开了二维数组为备忘录
4、心得体会
这道题的决策一开始有点难以理解,对每个决策时的状态分析不够透彻,还需要多打代码来提高自己对动态规划的理解。