问题:
编辑距离指的是将一个字符串转化成另一个字符串,需要的最少编辑操作次数(比如增加一个字符、删除一个字符、替换一个字符)。编辑距离越大说明两个字符串的相似程度越小,相反,编辑距离越小,说明两个字符串的相似程度越大。编辑距离有多种不同的计算方式,本节使用莱文斯坦距离,莱文斯坦距离允许增加、删除、替换字符这三个编辑操作。
代码:
1 #include <iostream> 2 #include <string.h> 3 4 int min3(int a, int b, int c) 5 { 6 int tmp = a < b ? a : b; 7 if(tmp < c) 8 return tmp; 9 return c; 10 } 11 12 // 求两个字符串的莱文斯坦距离 13 int main() 14 { 15 const char *a = "mitcmu"; 16 const char *b = "mtacnu"; 17 18 // 1、需要根据两个字符串的长度来创建状态数组,也就是状态转移表 19 int lena = strlen(a); 20 int lenb = strlen(b); 21 22 int **states = new int*[lena]; 23 for(int i = 0; i < lena; i++) 24 { 25 states[i] = new int[lenb]; 26 memset(states[i], 0, sizeof(int) * lenb); 27 } 28 29 // 2、初始化状态转移表 30 /* 31 m t a c n u 32 m 0 1 2 3 4 5 33 34 i 1 35 36 t 2 37 38 c 3 39 40 m 4 41 42 u 5 43 */ 44 // 初始化第一行 45 for(int i = 0; i < lenb; i++) 46 { 47 if(a[0] == b[i]) 48 states[0][i] = i; 49 else if(i != 0) 50 states[0][i] = states[0][i-1] + 1; 51 else 52 states[0][i] = 1; 53 } 54 55 // 初始化第一列 56 for(int j = 0; j < lena; j++) 57 { 58 if(b[0] == a[j]) 59 states[j][0] = j; 60 else if(j != 0) 61 states[j][0] = states[j-1][0] + 1; 62 else 63 states[j][0] = 1; 64 } 65 66 for(int i = 0; i < lena; i++) 67 { 68 std::cout << "[" << i << "] "; 69 for(int j = 0; j < lenb; j++) 70 { 71 std::cout << states[i][j] << " "; 72 } 73 std::cout << std::endl; 74 } 75 76 // 迭代递推状态转移表 77 for(int i = 1; i < lena; i++) 78 { 79 for(int j = 1; j < lenb; j++) 80 { 81 if(a[i] == b[j]) 82 states[i][j] = min3(states[i-1][j] + 1, states[i][j-1] + 1, states[i-1][j-1]); 83 else 84 states[i][j] = min3(states[i-1][j] + 1, states[i][j-1] + 1, states[i-1][j-1] + 1); 85 } 86 } 87 88 89 std::cout << "min_dist : " << states[lena - 1][lenb - 1] << std::endl; 90 91 92 for(int i = 0; i < lena; i++) 93 delete states[i]; 94 delete states; 95 96 return 0; 97 }
运行结果: