動態規劃--編輯距離問題
阿新 • • 發佈:2018-11-05
一、問題描述
設A和B是2個字串。要用最少的字元操作將字串A轉換為字串B。這裡所說的字元操作包括 (1)刪除一個字元; (2)插入一個字元; (3)將一個字元改為另一個字元。 將字串A變換為字串B所用的最少字元運算元稱為字串A到 B的編輯距離,記為d(A,B)。 對於給定的字串A和字串B,計算其編輯距離 d(A,B)。
輸入格式:
第一行是字串A,檔案的第二行是字串B。
提示:字串長度不超過2000個字元。
輸出格式:
輸出編輯距離d(A,B)
輸入樣例:
fxpimu
xwrs
輸出樣例:
5
二、演算法分析
我們把問題一步步執行,每一步的執行都依賴上一步的決策(刪除、插入、替換),即子問題具有重疊性,同時子問題的求解都有最佳決策,所以這是一個動態規劃問題。這裡定義一個二維陣列d[i][j]儲存操作,表示字串i到字串j的距離。
1)假如i長度大於j進行刪除做作使i變成j, 則此時d[i][j] = d[i - 1][j] + 1;
2)假如i長度小於j進行插入操作,即刪除j末尾元素, 使i與j相等, 則此時d[i][j] = d[i][j - 1] + 1;
3) 假如i長度等於j,則判斷i和j最後一個元素相不相等。若相等則d[i][j] = d[i-1][j-1] + 1.
得出遞迴公式:d[i][j] =min(d[i-1][j-1] + diff(), d[i][j-1]+1, d[i-1][j]+1)
三、程式碼
#include <iostream> #include<cstring> using namespace std; int min(int a, int b, int c) { int temp = a < b ? a : b; return temp < c ? temp : c; } int m(string a, string b) { int E[a.length() + 1][b.length() + 1]; // 初始化二維陣列 for (int i = 0; i <= a.length(); i++) { E[i][0] = i; } for(int i = 0; i <= b.length(); i++) { E[0][i] = i; } //演算法實現 for (int i = 1; i <= a.length(); i++) { for (int j = 1; j <= b.length(); j++) { int diff = (a[i - 1] == b[j - 1] ? 0 : 1);//diff表示相同則加0,不相同加1 E[i][j] = min(E[i - 1][j] + 1, E[i][j - 1] + 1, E[i - 1][j - 1] + diff); } } return E[a.length()][b.length()]; } int main() { string i, j; cin >> i >> j; cout << d(i, j) << endl;
四、時空分析
因為用了一個數組儲存兩層for,所以時間複雜度為O(i*j),空間複雜度為O(i*j)。
五、結對總結
通過互相講述做題過程,從而對題目有了一個更加清晰的認知,也對做題方法起到了很好的總結作用。