解题思路:
三种操作分别是:
插入
删除
替换
需要清楚的点:
两字符串A和B,给A插入相当于给B删除,反之亦然(例如cat和cate)
替换A相当于替换B(例如cat和fat)
故本质操作就三种 : ① A插 ② B插 ③ 替换
dp[i][j]表示从 A 的 前 i 个 字 符 转换到 B 的 前 j 个 字 符 所需的最短步数
(例如A是qwert B是aserty 那么最终输出结果就是dp[5][6])
dp[i-1][j-1]到dp[i][j]需要进行替换操作
若A的第 i 位(其实就是当前操作位)等于 B的第 j 位(其实就是当前操作位),那么就不需要替换,因此dp[i][j] = dp[i-1][j-1] ,否则dp[i][j] = dp[i-1][j-1]+1
dp[i-1][j]到d[i][j]需要进行删除操作
dp[i][j] = dp[i-1][j] + 1
dp[i][j-1]到d[i][j]需要进行添加操作
dp[i][j] = dp[i][j-1] + 1
★当A与B末位相同时:
dp[i][j] = min(dp[i][j−1]+1,dp[i−1][j]+1,dp[i−1][j−1])
★当A与B末位不相同时:
dp[i][j] =1+min(dp[i][j−1],dp[i−1][j],dp[i−1][j−1])
***那么,我们要怎么从dp[0][0] 到 dp[i][j]呢?
很简单,每一步做出判断,替换、删除、添加哪个短就选哪个!
这里需要注意,①dp[a][b]代表着前面所有步数的最短选择!②由于不知道AB长度,因此A插和B插不可以混为一谈!
注意事项:
边界情况,A或B为空,直接输出不为空的数组长度即可
参考代码:
#include
using namespace std;
int main(){
//注意!!数组是从0开始索引的,所以第i位就是i-1的索引,以此类推!!
string a,b;
getline(cin,a);
getline(cin,b);
int len1 = a.length();
int len2 = b.length(); //接受输入记录长度
int dp[len1][len2]; //定义dp数组
for (int i = 0; i < len1; i++) {dp[i][0] = i;}
for (int j = 0; j < len2; j++) {dp[0][j] = j;} //边界情况,同时也是初始化
for (int i = 1; i < len1; i++)
{
for (int j = 1; j < len2; j++) //ij从1开始,因为已经初始化过了,从0开始会溢出
{
if(a[i-1] == b[j-1]) //A的第i位与B的第j位相同的情况
dp[i][j] = min(min(dp[i][j-1]+1, dp[i-1][j]+1),dp[i-1][j-1]);
else
dp[i][j] = min(min(dp[i][j-1]+1, dp[i-1][j]+1),dp[i-1][j-1]+1);
}
}
cout<<dp[len1-1][len2-1]<<endl;
return 0;
}
0.0分
1 人评分
点我有惊喜!你懂得!浏览:2071 |
C语言程序设计教程(第三版)课后习题7.4 (C语言代码)浏览:552 |
C语言程序设计教程(第三版)课后习题5.4 (C语言代码)浏览:885 |
C语言程序设计教程(第三版)课后习题6.2 (C语言代码)浏览:1419 |
C语言程序设计教程(第三版)课后习题7.5 (C语言代码)浏览:519 |
C二级辅导-阶乘数列 (C语言代码)浏览:688 |
简单的a+b (C语言代码)浏览:523 |
简单的a+b (C语言代码)浏览:596 |
C语言程序设计教程(第三版)课后习题8.8 (C语言代码)浏览:1415 |
求圆的面积 (C语言代码)浏览:1667 |