一般情况下,电商在当客户输入一个不存在的商品时,会返回客户一个与客户输入最为接近的商品,并加以提示“您是不是在找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]
这一种是最为原始的递归算法:
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 }