算法第三章实验报告

1.1问题描述

                             7-4 编辑距离问题 (25 分)
 

设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。

输入格式:

第一行是字符串A,文件的第二行是字符串B。

提示:字符串长度不超过2000个字符。

输出格式:

输出编辑距离d(A,B)

输入样例:

在这里给出一组输入。例如:

fxpimu
xwrs 
 
结尾无空行

输出样例:

在这里给出相应的输出。例如:

5

1.2算法描述

(1)问题分析

  首先分析题目,根据题目,每一步编辑只有3种操作,即删除、替换、插入;设置表d[m][n],表示字符串a的前m位变成字符串b的前n位时要进行的最少编辑次数

  a的第m位字符不等于b的第n位时,有3种操作

  a[m]!=b[n]  d[m][n] = d[m-1][n]+1//删除操作 

  a[m]!=b[n]  d[m][n] = d[m-1][n-1]+1;//替换操作

  a[m]!=b[n]  d[m][n] = d[m][n-1]+1;//插入

  a的第m位字符等于b的第n位时,不用编辑,直接比较下一位

  s[m] == d[n]  d[m][n] = d[m-1][n-1];

  可以看出d[m-1][n-1]一定比d[m-1][n-1]+1小,所以当第m位等于第n位时,直接用d[m-1][n-1]和删除、插入操作比较,看哪个编辑次数最少

(2)代码

 


int write(int m, int n)//填表,m和n传进来的分别对应字符a和字符b要编辑的长度
{
    
    //填写边界条件
    for (int i = 0;i <= m;i++)
    {
//目标字符串长度为0时,字符a最少编辑次数为进行i次删除变成字符b d[i][
0] = i; } for (int i = 0;i <= n;i++) {
    //当字符a的长度为0时,字符a要进行i次插入操作变成字符b d[
0][i] = i; } //通过递归方程式填表 for (int i = 1;i <= m;i++) { int flag = 0; for (int j = 1;j <= n;j++) { if(a[i-1]==b[j-1]) { flag = 0; } else flag = 1; d[i][j] = min(d[i-1][j]+1,d[i-1][j-1]+flag,d[i][j-1]+1); } } return d[m][n]; }

 

1.3问题求解

(1)递归方程

  

(2)填表法中的表的维度、填表范围、填表顺序

  运用了二维表,从递归式可以看出的每次的d[m][n]都取决与子问题,取决于d[m][n]前一行或前一列的数据,故填表应该是从上往下、从左往右填,

  由此可得填表的范围是填完0-m行、0-n列的表格,

(3)算法的时间复杂度和空间复杂度

  时间复杂度为O(m*n),空间复杂度也为O(m*n)

(4)心得体会

这道题写出递归方程后由于细节问题,改了好久

①在分析问题,写递归方程式时,一定要注意观察,比如说当a[m]==b[n]时,插入操作的式子一定是比d[m-1][n-1]大一个1的,故插入操作其实可以不用比较了

一定要真正理解自己的d[m][n]具体是什么含义,一开始我的递归是这么写的,

if(a[m]==b[n]) d[m][n] = min(d[m-1][n]+1,d[m][n-1]+1,d[m-1][n-1])

然后运送结果错误,我一直不知道为什么,后来想想,我的d[m][n]是a的前m位变成b的前n位,那对a字符和b字符而言,第m位是a[m-1],,第n位是b[n-1]这样写,明显错了,同时判断a[0]和b[i]的结果存放在d[0][i]处时显然不符合d[0][i]的含义

③总之,写这道题让我发现,动态规划除了要认真写好规划方程,还要注意各个细节才能使代码得到的结果正确

1.4对动态归划法的理解和体会

①动态规划方法依赖于子问题,通过求解出子问题一步步递归求得原问题,有点像分治法;老师出的一些问题可以不用使用动态规划就可以写出来了,但是这些问题都相对简单,可以看出来,
如果是复杂的,无法看出来,还是得依靠动态规划

②动态规划的重点是求解出递归方程式,求解出递归方程后整个问题就可以迎刃而解,一个很难的问题,如果通过动态规划,得到它的递归方程式,整个问题就会变得很简单
③虽然得到递归方程式后问题会变得简单,但是要注意细节问题,和边界条件,一个递归方程要有终止条件,而边界条件有时也会因为题目的要求不同,参考此处最大子段和,
当全为负数时,边界条件为0
④最后是,个人觉得还是得多练习相关题目,才能更容易写出递归方程并根据题目的不同注意各样的细节问题

 

posted @ 2021-10-31 12:37  式微之子于微  阅读(46)  评论(0编辑  收藏  举报