2018.8.17 題解 2018暑假集訓之編輯距離
阿新 • • 發佈:2018-08-17
msu type ring clu span 插入 pan -h 俄羅斯
應該是一個很經典的題目了吧
上題面描述
概念
字符串的編輯距離,又稱為Levenshtein距離,由俄羅斯的數學家Vladimir Levenshtein在1965年提出。是指利用字符操作,把字符串A轉換成字符串B所需要的最少操作數。其中,字符操作包括:
- 刪除一個字符 a) Insert a character
- 插入一個字符 b) Delete a character
- 修改一個字符 c) Replace a character
例如對於字符串"if"和"iff",可以通過插入一個‘f‘或者刪除一個‘f‘來達到目的。
一般來說,兩個字符串的編輯距離越小,則它們越相似。如果兩個字符串相等,則它們的編輯距離(為了方便,本文後續出現的“距離”,如果沒有特別說明,則默認為“編輯距離”)為0(不需要任何操作)。不難分析出,兩個字符串的編輯距離肯定不超過它們的最大長度(可以通過先把短串的每一位都修改成長串對應位置的字符,然後插入長串中的剩下字符)。
問題描述
給定兩個字符串A和B,求字符串A至少經過多少步字符操作變成字符串B。
對於這個問題來講我們首先想到的是用bfs解決
然而發現會TLE Q_Q
對於求最值的問題,我們考慮搜索、dp、貪心
已經排除搜索(同樣易證得貪心不可行)於是考慮用dp解決
本題有一個很類似的問題 題目傳送門 同樣是對兩個字符串上的dp
同樣的在前面我們講過一個紙牌問題解決如何“兩個同時取”
而這個題只有兩個變量 就是兩個串取到了第幾個位置
綜上所述
我們分兩種情況考慮
(1)a[i]==b[j] dp[i][j]=dp[i-1][j-1](該字符不變)
(2)a[i]!=b[j] dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1(更改、插入、刪除)
上代碼吧
#include<iostream> #include<cstring> using namespace std; int dp[3050][3050],lena,lenb,a[3050],b[3050]; int main() { gets(a+1),gets(b+1); lena=strlen(a+1),lenb=strlen(b+1); for(int i=1;i<=lena;i++)dp[i][0]=i; for(int j=1;j<=lenb;j++)dp[0][i]=i; for(int i=1;i<=lena;i++) { for(int j=1;j<=lenb;j++) { if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]; else dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]+1)); } } printf("%d",dp[lena][lenb]); return 0; }
也是一個經典的字符串dp題目
2018.8.17 題解 2018暑假集訓之編輯距離