動態規劃C++實現--最小編輯代價
題目:給定兩個字串 str1 和 str2,再給定三個整數 ic, dc 和 rc,分別代表插入、刪除和替換1個字元的代價,
返回 str1 編輯成 str2 的代價。
舉例:
str1 = "abc", str2 = "adc", ic = 5, dc = 3, rc = 2. : "b"替換成"d"代價為 2
str1 = "abc", str2 = "adc", ic = 5, dc = 3, rc = 100 : 先刪除"b",再插入"d"代價為8
str1 = "abc", str2 = "abc" 兩個字串相同,不用編輯了,代價為0.
方法:
如果 str1 的長度為 M,str2的長度為 N,採用動態規劃的方法,時間複雜度為 O(M*N) ,額外的空間複雜度為O(M*N)
首先生成動態矩陣 dp[M+1][N+1],其中 dp[i][j] 表示 st1[0,...,i-1] 編輯成 str2[0,...,j-1]的最小代價。
1. 首先動態矩陣的初始值 dp[0][0] = 0
2. 動態矩陣的第一列 dp[0,...,M-1][0] . dp[i][0] 表示 str1[0,...,i-1]編輯成空串的代價,即刪除(dc)所有字元,
dp[i][0] = dc * i ;
3. 動態矩陣的第一行 dp[0][0,...,N-1] . dp[0][j] 表示 空串編輯成 str2[0,...,j-1]的代價,即插入(ic)所有字元,
dp[0][j] = ic * j ;
4. 其他位置進行填充 dp[i][j]
① str1 先刪除(dc)一個字元,dp[i][j] = dc + dp[i-1][j] ;
具體來說,str1[0,...,i-1] 先刪除 str[i-1],得到 str1[0,...,i-2], 再由str1[0,..., i-2] 編輯成 str2[0,...,j-1]. (dp[i-1][j])
② str2 後插入(ic)一個字元 ,dp[i][j] = dp[i][j-1] + ic ;
具體來說,str1[0,...,i-1] 先編輯成 str2[0,..., j-2] (dp[i][j-1]), 再由 str2[0,...,j-2] 插入一個 str2[j-1] 編輯成str2[0,...,j-1]
③ 若 str1[i-1] != str2[j-1] ,替換(rc) str1[i-1] 的字元, dp[i][j] = dp[i-1][j-1] + rc ;
若 str1[i-1] == str2[j-1] , dp[i][j] = dp[i-1][j-1] ;
程式碼如下:
// 最小編輯代價 <動態規劃> <複雜度0(M*N)>
#include<bits/stdc++.h>
using namespace std;
int mincost1(string str1, string str2, int ic, int dc, int rc);
int main(){
string str1, str2;
cin>>str1;
cin>>str2;
int ic = 5; //插入一個字元的代價
int dc = 3; //刪除一個字元的代價
int rc = 2; //替換一個字元的代價
int result = mincost1(str1, str2, ic, dc, rc);
cout<< result;
return 0;
}
int mincost1(string str1, string str2, int ic, int dc, int rc){
int row = str1.size() + 1;
int col = str2.size() + 1;
vector<vector<int>> dp(row, vector<int>(col, 0));
//考慮邊界,第一列,第一行
for(int i = 1; i < row; i++){
dp[i][0] = dc * i;
}
for(int j = 1; j < col; j++){
dp[0][j] = ic * j;
}
//其他位置進行從左到右,從上到下的填充
for(int i = 1; i < row; i++){
for(int j = 1; j < col; j++){
if(str1[i-1] != str2[j-1]){
dp[i][j] = dp[i-1][j-1] + rc;
}else{
dp[i][j] = dp[i-1][j-1];
}
dp[i][j] = min(dp[i][j], dc + dp[i-1][j]);
dp[i][j] = min(dp[i][j], dp[i][j-1] + ic);
}
}
return dp[row-1][col-1];
}
/* input
ab12cd3
abcdf
*/
/* output
8
*/
編譯環境:codeblocks
輸入:
輸出:
未完:結合空間壓縮的方法,可以將額外空間複雜度降低為O(min(M,N))