編輯距離
- 本題與力扣72.編輯距離題意一樣,閱讀完本文可以嘗試leetcode72.
力扣題目連結
題目敘述
輸入兩個字串a,b。輸出從字串a修改到字串b時的編輯距離
輸入
NOTV
LOVER
輸出
4
題目解釋:
動態規劃思路
- 這個問題顯然是一個最優解問題,我們可以考慮動態規劃的思路,那麼我們使用動態規劃的思路,要想得到最優解問題,那麼我們必須要先考慮子問題。
- 子問題:我們先考慮
a[1,2...i]
到b[1,2....j]
的編輯距離
狀態變數的含義
- 設立一個
dp陣列
,作為我們的狀態變數dp[i][j]
表示以從a[1...i]
到b[1....j]
的編輯距離
遞推公式
- 設立完狀態變數,那麼我們就進入了遞推公式的推導
- 1.若
a[i]
=b[j]
,那麼dp[i][j]==dp[i-1][j-1]
- 2.
a[i]!=b[j]
- 1.若
- 那麼我們就很容易的推出我們的遞推公式:
dp[i][j]
=dp[i-1][j-1]
(a[i]==b[j]
)dp[i][j]=min(dp[i-1][j-1],dp[i][j-1],dp[i-1][j])+1
)(a[i]!=b[j]
)
遍歷順序
- 顯然是從上到下,從左到右。
初始化dp陣列
-
邊界條件:
f[i][0]=i
f[0][j]=j
-
對應的初始化程式碼如下:
m=strlen(a);
n=strlen(b);
for(int i=1;i<=m;j++) dp[i][0]=i;
for(int j=1;j<=n;j++) dp[0][j]=j;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1];
else dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j])+1;
}
}
cout<<f[m][n];
舉例列印dp陣列
- 舉例如下:
程式碼
- 最終實現程式碼如下:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char a[2005],b[2005];
int f[2005][2005];
int main(){
scanf("%s %s",a,b);
int la=strlen(a), lb=strlen(b);
for(int i=1;i<=la;i++) f[i][0]=i;
for(int i=1;i<=lb;i++) f[0][i]=i
for(int i=1;i<=la;i++)
for(int j=1;j<=lb;j++)
if(a[i-1]==b[j-1])f[i][j]=f[i-1][j-1];
else f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
printf("%d\n",f[la][lb]);
}