1. 程式人生 > >2018.8.17 題解 2018暑假集訓之編輯距離

2018.8.17 題解 2018暑假集訓之編輯距離

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暑假集訓之編輯距離