您的位置:首页 > 其它

最小编辑代价 动态规划

2017-12-10 21:30 211 查看
1、题目描述:来源于《算法与数据结构题目最优解》左程云著

给定两个字符串str1和str2,再给定三个整数ic、dc和rc,分别代表插入、删除和替换一个字符的代价,返回将str1编辑成str2的最小代价

2、输入

abc
adc
5 3 2
abc
adc
5 3 100
abc
abc
5 3 2
ab12cd3
abcdf
5 3 2

3、输出

2
8
0
8

4、题目解析
1)题目的关键还是在于找状态,这个题目的状态dp[i][j]就代表用str1的前 i 位 编辑成 str2 的前 j 位的最小代价。
2)关键点之二在于初始状态的时候,字符串的初始状态一般是空字符串,这样考虑起来就比较容易了,我一开始是从第一个字符开始的,其实也可以,不过不如空串直观。
3)关键点之三在于状态的迭代,这个的情况比较多,想从str1的前 i 个得到 str2的前 j 个,
a、可以是前 i-1 个组成了 前 j-1 个,这样就用str1第 i 个 替换成str2的第 j 个就行了,不过如果str1[i]==str2[j],
就不用替换了(我就没考虑到这种情况);
b、可以是前 i-1个组成了前 j 个,那么只需要删除第 i 个
c、可以是前 i 个组成了前 j-1 个,那么只需要再插入一个。

5、代码如下:
#include<iostream>
#include<vector>
#include<string>

using namespace std;
int getMin(int, int);
int main() {
string str1, str2;
int ic, dc, rc;//插入、删除、替换
int len1, len2;
int i, j;
getline(cin, str1);
getline(cin, str2);
cin >> ic >> dc >> rc;
len1 = str1.length();
len2 = str2.length();
vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1));//dp[i][j]代表用去str1的前i为变成str2的前j位的最小代价,并且初始化从空字符串开始
//下面对dp进行赋值,从dp[0][0]代表空字符串
dp[0][0] = 0;
for (i = 1; i < len1 + 1; ++i) {
dp[i][0] = dp[i - 1][0] + dc;
}
for (j = 1; j < len2 + 1; ++j) {
dp[0][j] = dp[0][j - 1] + ic;
}
for (i = 1; i < len1 + 1; ++i) {
for (j = 1; j < len2 + 1; ++j) {
if (str1[i] == str2[j])//一定要注意考虑str1[i]是否和str2[j]相等
dp[i][j] = dp[i - 1][j - 1];
else
dp[i][j] = dp[i - 1][j - 1] + rc;
dp[i][j] = getMin(dp[i][j],dp[i][j-1]+ic);
dp[i][j] = getMin(dp[i][j], dp[i - 1][j] + dc);
}
}
cout << "the minimum value is: " << dp[len1][len2] << endl;
}
int getMin(int v1, int v2) {
if (v2 < v1)return v2;
return v1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: