動態規劃之編輯距離:用最少的字元操作將A變換成B
阿新 • • 發佈:2019-01-08
一、問題描述
設A和B是兩個字串,長度分別為n,m要用最少的字元操作(包括字元的插入、刪除、修改),這樣的操作稱為字串A到B的操作距離,記為d(A,B)。
二、思路分析
把求解編輯距離分為字串A從0個字元逐漸增加到全部字元分別要變成字串B該如何變化的問題。具體來說就是,首先選用str1來儲存字串A,str2來儲存字串B,distance矩陣來進行具體的運算。考慮到最簡單的情況,str1的長度為0,str2長度不為0;str1長度不為0,str2長度為0,對前一種情況的編輯距離就是m,後一種則是n。為什麼?因為str1為0的時候要麼對str1進行新增,即新增m位的str2,要麼對str2進行m個刪除操作;str2為0的時候,要麼對str1進行n個刪除操作,要麼對str2進行n個新增操作。接下來我們著重考慮一般情況,distance矩陣為[n][m],假定我們從distance[0][0]開始一直操作到了distance[i][j]位置,其中刪除操作肯定是str1比str2長,插入操作str1比str2短,我們所要做的是對distance[i-1][j] 、distance[i][j-1]、distance[i-1][j-1]存的數進行比較,其中最小的就是當前str1和str2的編輯距離。
三、實現過程
這裡,我們把矩陣抽象出來,
abc | a | b | c | |
abe | 0 | 1 | 2 | 3 |
a | 1 | A處0 | D1 | G 2 |
b | 2 | B處1 | E0 | H 1 |
e | 3 | C處2 | F1 | I 1 |
四、程式碼實現
#include<iostream> using namespace std; #define MAX 100 //求三者中的最小值 int minval(int a,int b,int c){ int zhi=min(a,b); int minvalue=min(zhi,c); return minvalue; }
//求二者中的最小值 int min(int a,int b){ return(a>b?b:a); } //編輯距離函式,str1 str2為操作的字串 void editDistance(char *str1,char *str2){ int lenthofstr1=strlen(str1); int lenthofstr2=strlen(str2); int distance[MAX][MAX]; //變數用來遍歷、初始化字串 int i,j; for(i=0;i<lenthofstr1;i++){ distance[i][0]=i; } for(i=0;i<lenthofstr2;i++){ distance[0][i]=i; } for(i=1;i<lenthofstr1;i++){ for(j=1;j<lenthofstr2;j++){ //如果對應的字元相等,原問題交給子問題處理,即不用任何操作 if(str1[i]==str2[j]){ distance[i][j]=distance[i-1][j-1]; } else{ //否則的話,對左、右、左上角的值進行求最小值 distance[i][j]=minval(distance[i-1][j]+1,distance[i][j-1]+1,distance[i-1][j-1]+1); } cout<<distance[i][j]<<" "; } cout<<endl; } cout<<"最少的操作次數是:"<<distance[lenthofstr1-1][lenthofstr2-1]; } int main(){ char str1[]={"abc"}; char str2[]={"dabc"}; editDistance(str1,str2); return 0; } 五、結果顯示