最小編輯代價(編輯距離問題改進版)
阿新 • • 發佈:2021-05-30
題目描述
給定兩個字串str1和str2,再給定三個整數ic,dc,rc,分別代表插入、刪除、替換一個字元的代價,返回將str1編輯成str2的最小代價。
該題是基於經典動態規劃問題編輯距離的改進版編輯距離問題
輸入輸出樣例
輸入1
str1=“abc” str2=“adc” ic=5 dc=3 rc=2
從"abc"編輯到"adc"把b替換成d代價最小,為2;
輸出1
2
輸入2
str1=“abc” str2=“adc” ic=5 dc=3 rc=10
從"abc"編輯到"adc",先刪除b再插入d代價最小,為8;
8
思路解析
動態規劃問題大多都是求最值問題,求最值意味著要先窮舉才能求最值。
約定
約定DP表即二維陣列A[i][j]
,表示由字串A的前i
位變成字串B的前j
位,所形成的兩個字串變換所需要的最小編輯距離。
初始化
如果兩個字串中有一個字串是空,那麼另外一個字串變成它需要插入操作即可。
for(i=0;i<=s1.length();i++)
{
a[i][0] = i*ic;
}
for(j=0;j<=s2.length();j++)
{
a[0][j] = j*ic;
}
狀態轉移方程
出了上述初始化部分,我們要考慮四種情況:
1.如果字串S1和S2的末尾字元相同,即S1[i-1]==S2[j-1]
2.如果末尾不相同,那麼就意味著需要進行變換,可以由不同的情況通過插入、刪除、替換三種操作來實現,而題目要求找最小代價,那麼求這三種對應的最小操作就行。
- 替換:
a[i-1][j-1]+uc
- 插入/刪除(插入或刪除都可以):
a[i-1][j]+dc,a[i][j-1]+ic
C++ 實現
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void printDP(int a[100][100],int q,int p)
{
int i,j;
for(i=0;i<q;i++)
{
for(j=0;j<p;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
// DP表要當代價的
int minPrice(string s1,string s2,int ic,int dc,int uc)
{
// i j 代表兩個字串的前n個字元比對
int a[100][100];
int i,j;
// base case 插入所需代價
for(i=0;i<=s1.length();i++)
{
a[i][0] = i*ic;
}
for(j=0;j<=s2.length();j++)
{
a[0][j] = j*ic;
}
// 都不是空串的情況
for(int i=1;i<=s1.length();i++)
{
for(int j=1;j<=s2.length();j++)
{
// 若末尾兩字元相同
if(s1[i-1]==s2[j-1])
{
// 不需要進行任何操作,即前i個與前j個組成的字串與前i-1和前j-1個組成的字串代價是相同的
a[i][j]==a[i-1][j-1];
}else{
// 進行插入刪除編輯
a[i][j]=min(a[i-1][j-1]+uc,min(a[i-1][j]+dc,a[i][j-1]+ic));
}
}
}
printDP(a,s1.length(),s2.length());
return a[s1.length()-1][s2.length()-1];
}
int main()
{
cout<<minPrice("abc","adc",5,3,10);
return 0;
}