編輯距離問題(Edit Distance Problem)
阿新 • • 發佈:2017-10-10
三種 距離 del 計算 第一個 單個 main iostream namespace
問題描述
設A和B是兩個字符串,要用最少的字符操作將字符串A轉換成字符串B。這裏所說的字符操作包括
1)刪除一個字符;
2)插入一個字符;
3)將一個字符改為另一個字符。
將字符串A變換為字符串B所用的最少字符操作數成為字符串A到B的編輯距離,記為d(A,B)。對任給的2個字符串A和B,計算出它們的編輯距離d(A,B)。
問題分析
這是一道DP問題,DP問題的核心是“全局最優解的部分解是部分子問題的最優解”。構造字符串A,B如下
A: abcdef
B: acdefgh
全局最優解B=“abcdef”的部分解B1=“abcde”,是部分子問題A1=“abcde”,B1="acdef"的最優解,抓住此關鍵點,可知應對單個字符進行考慮,進而求出整個字符串的最優解。對第一個字符,B中的’a‘與A中的’a‘相同,因此可以不操作;第二個字符,B中的’c‘與A中的’b‘不同,則此時有三種情況:
1)刪除’c‘
2)插入’b‘
3)將’c‘改為’b‘
計算三種情況下兩個字符串中位置相同且字符相同的字符數量,選擇最大那種方法,然後進行下一個字符的計算。遇到多余的字符,則直接刪去並將編輯距離增加即可。此例中的計算步驟即為“acdefgh”=>"abcdefgh"=>"abcdef"。
#include<iostream> #include<string> using namespace std; int getEqualsNum(string &a, string &b) { int num = 0; for (unsigned int i = 0; i < a.length()&&i<b.length(); i++) { if (a[i] == b[i])num++; } return num; } int max(int a, int b, int c) { if (a > b&&a > c)return 1; if (b > a&&b > c)return 2; return 3; } int main() { string a, b; a = "abcdef"; b = "acdefg"; int res = 0; for (unsigned int i = 0; i < a.length()&& i < b.length(); i++) { if (a[i] == b[i])continue; else { //獲取三種操作後的字符串與A串相等字符的個數 int add, del, change; string c; c = b; c.insert(i, a, i); add = getEqualsNum(a, c); c = b; c.erase(i, 1); del = getEqualsNum(a, c); c = b; c[i] = a[i]; change = getEqualsNum(a, c); //選取最優字串,對B串進行處理 int temp; temp = max(add, del, change); if (temp == 1)b.insert(i, a, i,1); else if (temp == 2)b.erase(i, 1); else b[i] = a[i]; res++; } } int len1 = a.length(), len2 = b.length(); res += (len1 - len2) >= 0 ? (len1 - len2): -(len1 - len2); cout << "A:" << a << endl << "B:" << b << endl; cout << "Eidt Distance:" << res << endl; system("pause"); return 0; }
編輯距離問題(Edit Distance Problem)