算法第三章上机实践报告

1.1 问题描述

设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)

 

1.2 算法描述

通过找规律找到删除,插入,修改这三个操作的状态转移方程。

定义dp[i][j]为:把串A的第1到i位变成串B的第1到j位的最小步骤。(从1开始,因为0表示空串)。

然后i从1-A.size()遍历,j从1-B.size()遍历——答案就是dp[A.size()][B.size()];

 

1.3 问题求解:

1.1.1 根据最优子结构性质,列出递归方程式

修改:

令string a="ab",string b="ac";想让ab变成ac,其实就是让ab、ac都退一步变为a、a,然后把a加上c;

退一步就是变成dp[i-1][j-1],加c就是再+1;

即:dp[i][j]=dp[i-1][j-1]+1;

 

插入:

一般情况下,如果要插入,那么A.size()<B.size();

令string a="ab",string b="cde";

想让ab变成cde:ab先变成cd,再+e;

ab变成cd即dp[i][j]=dp[i][j-1];

加e即要+1;

即:dp[i][j]=dp[i][j-1]+1;

 

删除:与插入同理。

dp[i][j]=dp[i-1][j]+1;

 

1.1.2 给出填表法中表的维度、填表范围和填表顺序。

维度:二维。因为要字符串逐一比较。

填表范围:i从1到a.size(),j从1到b.size();

填表顺序:外层循环i,从1加到a.size();内层循环j,从1加到b.size()。

 

1.1.3 分析该算法的时间和空间复杂度

时间复杂度:O(n2)  二重循环。

空间复杂度:O(n2)  二维数组。

 

1.3 心得体会(对本次实践收获及疑惑进行总结)

本次实验四道题正好是四种动态规划典型题。

最低通行费:二维数组,规定了只能走的方向(右,下),那么每个点都只能从左、上得到(除了边界),是一个斐波那契数列变形。

最大子段和:前面的数字和不是负数就可以加上。每个dp[i]都要看dp[i-1]。经典的动态规划。

单调递增最长子序列:跟最大字段和类似。

编辑距离问题:可以体现dp定义的妙处。

本次实验的四道题能让我们明显的体会到动态规划的特点、共性,更深刻的了解了动态规划的思想。

 

2.你对动态规划算法的理解和体会

动态规划,是利用历史记录避免重复计算的一种算法,是求解决策过程最优化的过程。

因此,很多求“最长最短”“最大最小”都可以用动态规划。

“将原问题拆解成若干子问题,同时保存子问题的答案,使每个子问题只求解一次,最终获得原问题的答案。”

 

posted @ 2021-10-21 21:04  karshey  阅读(41)  评论(0编辑  收藏  举报