题目描述
给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
示例1
输入 “abc”,“adc”,5,3,2
返回值 2
示例2
输入 “abc”,“adc”,5,3,100
返回值 8
备注:
1≤|str1|,|str2|≤5000
1≤ic,dc,rc≤10000
这题好难,看了网上各路大神的代码最后模仿写的。
主要创建一个数组dp,记录str1子串转化为str2子串的最小代价。dp[i][j]表示长度为i的第一个字符串编辑成长度为j的第二个字符串消耗的最小代价。
假设str1的长度为len1,str2的长度为len2,首先生成大小为(len1+1)*(len2+1)的矩阵dp,dp[i][j]的值代表str1[0…i-1]编辑成str2[0…j-1]的最小代价。
比如str1=“ab12cd3”,str2=“abcdf”,ic=5,dc=3,rc=2。
如果str1[i-1] == str2[j-1],则只需要将前i-1个字符转换为前j-1个字符即可,最后一个字符不动:dp[i][j] = dp[i-1][j-1]
如果str1[i] != str2[j]有三类操作可以使得str1变成str2,取其中的最小值:
1.插入:将i个字符串转变为前j-1个字符串在插入第j个字符 dp[i][j-1]+ic
dp[i][j-1]是实现字符串str1[0…i-1]转变为字符串str2[0…j-2]的最小代价,再插入一个字符,就实现str1到str2的转变。
2.删除:将i-1个字符串转换为前j个字符串删除第i个字符 dp[i-1][j]+id
dp[i-1][j]是实现字符串str1[0…i-2]转变为字符串str2[0…j-1]的最小代价,再删除一个字符,就实现str1到str2的转变。
3.替换:将i-1个字符串转换为前j-1个字符串替换掉第i个字符为第j个字符 dp[i-1][j-1]+rc
dp[i-1][j-1]是实现字符串str1[0…i-2]转变为字符串str2[0…j-2]的最小代价,再更改一个字符,就实现str1到str2的转变。
例如上图中的第二行第三列的5,
插入操作是将a先转变成a,代价是dp[1][1]=0,再插入字符b;
删除操作是将空字符串先转变为ab,代价是dp[0][2]=10,由于原第一个字符串有a,因此需要删除一个字符;
替换操作是将空字符串先转变为a,代价是dp[0][1]=5,再将a转变为b需要替换操作;
参考了的链接:
https://www.cnblogs.com/lutaishi/p/13436213.html
https://www.cnblogs.com/sidewinder/p/13750134.html
https://www.nowcoder.com/questionTerminal/05fed41805ae4394ab6607d0d745c8e4?answerType=1&f=discussion
C++实现:
#include<algorithm>
#include<vector>
class Solution {
public:
/**
* min edit cost
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @param ic int整型 insert cost
* @param dc int整型 delete cost
* @param rc int整型 replace cost
* @return int整型
*/
int minEditCost(string str1, string str2, int ic, int dc, int rc) {
// write code here
int len1=str1.size();
int len2=str2.size();
vector<vector<int> > dp(len1 + 1, vector<int>(len2 + 1));
int i=0,j=0;
dp[0][0]=0;
for(i=0,j=0;j<=len2;j++) //计算第一行,全是插入操作
{
dp[i][j]=ic*j;
}
for(i=0,j=0;i<=len1;i++) //计算第一列,全是删除操作
{
dp[i][j]=dc*i;
}
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
dp[i][j]=dp[i-1][j-1];
}
else{
int Min;
Min=min(dp[i-1][j]+dc,dp[i][j-1]+ic);
Min=min(Min,dp[i-1][j-1]+rc);
dp[i][j]=Min;
}
}
}
return dp[len1][len2];
}
};