最短編輯距離演算法

期待一片自己的藍天發表於2014-08-09

一般情況下,電商在當客戶輸入一個不存在的商品時,會返回客戶一個與客戶輸入最為接近的商品,並加以提示“您是不是在找XXX?”。這其中用到了一種演算法,叫做“最短編輯距離演算法”,能在一大堆已存在的字串中找到與原字串最為接近的那個字串,稱之為最短編輯距離。

這種演算法是基於動態規劃思想,下面是演算法的思路描述:

描述:

設A和B是2個字串。要用最少的字元操作將字串A轉換為字串B。這裡所說的字元操作包括:

(1)刪除一個字元;
(2)插入一個字元;
(3)將一個字元改為另一個字元。
將字串A變換為字串B所用的最少字元運算元稱為字串A到B的編輯距離,記為d(A,B)。試設計一個有效演算法,對任給的2個字串A和B,計算出它們的編輯距離d(A,B)。
要求:
輸入:第1行是字串A,第2行是字串B。
輸出:字串A和B的編輯距離d(A,B)

 

思路:

開一個二維陣列d[i][j]來記錄a0-ai與b0-bj之間的編輯距離,要遞推時,需要考慮對其中一個字串的刪除操作、插入操作和替換操作分別花費的開銷,從中找出一個最小的開銷即為所求

具體演算法:

首先給定第一行和第一列,然後,每個值d[i,j]這樣計算:d[i][j]   =   min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+(s1[i]  ==  s2[j]?0:1));  
 最後一行,最後一列的那個值就是最小編輯距離 。


這一種是最為原始的遞迴演算法:

int med(const string &x, int i, const string &y, int j)
 11 {
 12     count ++;
 13     if(i == 0)
 14         return j;
 15     if(j == 0)
 16         return i;
 17     if(x[i-1] == y[j-1])
 18         return  med(x, i-1, y, j-1);
 19     else{
 20         int a = med(x, i, y, j-1);
 21         int b = med(x, i-1, y, j);
 22         int c = med(x, i-1, y, j-1);
 23         int temp;
 24         return (((temp = (a < b ? a : b)) < c ? temp : c) + 1);
 25     }
 26 }        


這一種是帶有備份功能的遞迴演算法:

int med1(const string &x, int i, const string &y, int j)
 29 {
 30     if(backup[i][j] != -1)
 31         return backup[i][j];
 32     count ++;
 33     if(i == 0){
 34         backup[i][j] = j;
 35         return j;
 36     }
 37     if(j == 0){
 38         backup[i][j] = i;
 39         return i;
 40     }
 41     if(x[i-1] == y[j-1]){
 42         backup[i-1][j-1] = med1(x, i-1, y, j-1);
 43         return backup[i-1][j-1];
 44     }
 45     else{
 46         int a = med1(x, i, y, j-1) + 1;
 47         int b = med1(x, i-1, y, j) + 1;
 48         int c = med1(x, i-1, y, j-1) + 1;
 49         int temp;
 50         backup[i][j] = (temp = a < b ? a : b) < c ? temp : c;
 51         return temp;
 52     }
 53 }


這一種是非遞迴的演算法:

int med2(const string &x, int m, const string &y, int n)
 56 {
 57     for(int i = 0; i <= n; ++i)
 58         backup[0][i] = i;
 59     for(int i = 0; i <= m; ++i)
 60         backup[i][0] = i;
 61     for(int i = 1; i <= m; ++i){
 62         for(int j = 1; j <= n; ++j){
 63             if(x[i-1] == y[j-1])
 64                 backup[i][j] = backup[i-1][j-1];
 65             else{
 66                 int a = backup[i-1][j];
 67                 int b = backup[i][j-1];
 68                 int c = backup[i-1][j-1];
 69                 int temp;
 70                 backup[i][j] = ((temp = a < b ? a : b) < c ? temp : c) + 1;
 71             }
 72         }
 73     }
 74     return backup[m][n];
 75 }


相關文章