計算字符串距離
Description
- 對於兩個不同的字符串,我們有一套操作方法來把他們變得相同,具體方法爲:
- 修改一個字符(如把“a”替換爲“b”)
- 刪除一個字符(如把“traveling”變爲“travelng”)
- 增加一個字符(如把“son”改成“song”)
給定任意兩個字符串,寫出一個算法來計算出他們的距離。
Input
- 第一行有一個整數n。表示測試數據的組數,
接下來共n行,每行兩個字符串,用空格隔開。表示要計算距離的兩個字符串
字符串長度不超過1000。
Output
- 針對每一組測試數據輸出一個整數,值爲兩個字符串的距離。
Sample Input
-
3 abcdefg abcdef ab ab mnklj jlknm
Sample Output
-
1 0 4
題目解析
這道題的要求就是求最短編輯距離,所謂編輯距離(簡稱ED),是指兩個字符串之間,由一個轉成另一個所需的最少編輯操作次數(編輯操作有三種:將一個字符替換成另一個字符、插入一個字符、刪除一個字符)。它的公式如下:
if(a[i-1]==b[j-1])
f[i][j]=f[i-1][j-1];
else
f[i][j]=1+min(f[i-1][j-1],f[i][j-1],f[i-1][j]);接下來,爲了使大家更清楚最短編輯距離,我製作了3個表(樣例中的3組數據),具體如下:
0 a b c d e f 0 0 1 2 3
4 5 6 a 1 0 1 2 3 4 5 b 2 1 0 1 2 3 4 c 3 2 1 0 1 2 3 d 4 3 2 1 0 1 2 e 5 4 3 2 1 0 1 f 6 5 4 3 2 1 0 g 7 6 5 4 3 2 1
0 a b 0 0 1 2 a 1 0 1 b 2 1 0
0 j l k n m 0 0 1 2 3 4 5 m 1 1 2 3 4 4 n 2 2 2 3 3 4 k 3 3 3 2 3 4 l 4 4 3 3 3 4 j 5 4 4 4 4 4
代碼實現
代碼(DP)如下:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; char a[1001],b[1001]; int lena,lenb,f[1001][1001]; int min(int x,int y,int z) //algorithm庫的min只有兩個參數(即只能對兩個數進行判定),所以我自己寫了一個min函數 { if(x<=y&&x<=z) return x; else if(y<=x&&y<=z) return y; else return z; } main() { int n; cin>>n; //輸入測試數據數 while(n--) { scanf("%s%s",a,b); //本人不才,不太會用string,所以用了字符數組(用string也可以) lena=strlen(a); //存儲a字符數組的長度 lenb=strlen(b); //存儲b字符數組的長度 for(int i=0;i<=lena;i++) for(int j=0;j<=lenb;j++) { if(!i) //給第一列賦值 { f[i][j]=j; continue; } if(!j) //給第一行賦值 { f[i][j]=i; continue; } /*這裏就是最短編輯距離的公式*/ if(a[i-1]==b[j-1]) //若兩子串的最後一個字符相等,那它們的最短編輯距離就跟刪掉最後一個字符後的最短編輯距離相等 f[i][j]=f[i-1][j-1]; else //在替換、插入、刪除中選擇令兩個字符串編輯距離最少的,並加上1(當末尾字符不相等時) f[i][j]=1+min(f[i-1][j-1],f[i][j-1],f[i-1][j]); } cout<<f[lena][lenb]<<endl; } }