Edit Distance(编辑距离)算法。计算两个字符串的相似程度。

最近需要做两个字符串的相似度比较,涉及到了这个算法,于是写一篇博客记录一下。

      算法简介

Edit Distance 算法,又称Levenshtein Distance(LD)算法,以下简称LD,LD 可以衡量两字符串的相似性。

     距离的概念

      算法里主要涉及的就是一个距离的概念(名字里带的就是。。)
      距离,就是对于当前的两个字符串,要从 一个字符串转换成另一个字符串的过程中的添加、删除、修改的次数。
     比如: 
                                            string_1 = "abc"; 
                                            string_2 =  "abd";
       则,从string_1 转换到string_2 只需要 把 字符‘c’,转换成字符 'd'就行了,这只需要一次修改。 于是string_1 到string_2 的距离是 1。
      显然,当两个字符串的距离越大,这两个字符串的相似度就越低。

算法的思路

   先求出这两个字符串的长度。 
                                                    int m = string_1.length();
                                                    int n = string_2.length();
    显然,若 m,n中有一个是0,就不用比了,返回另一个的长度就行了。(显然这就是距离了)。
    若都不是0,那么,需要计算string_1 到string_2 需要修改多少遍了。于是,为了计算方便,
    初始化一个 (M+1)*(N+1)的矩阵来存     int[][] different = new int[m+1][n+1];
     注意,这个时候,为了高效计算,需要将  different 数组的第一行 也就是different[i][0]和第一列也就是different[0][i] 随i,从0开始递增。
   接下来就是处理字符串了。 从头开始扫描这两个字符串,用 i,j来分别表示扫描到了string_1 和string_2的位置。
  这时候,需要一个临时变量来记录 两个字符串中的某一位置的字符时候一样。
       int temp = 1;//  1表示不同,0,表示相同。
   显然: 
[cpp]  view plain copy print ?
  1. if(string_1[i]==string_2[j]){  
  2.             temp = 0;  
  3. }else{  
  4.        temp = 1;  
  5.       }  
  接下来就是关键了:
   我们需要从  different [i-1][j]+1,  different [i][j-1]+1,和 different[i-1][j-1]+temp 中选一个最小的将它的值赋给different [i][j]; 
扫描完之后,我们就可以来计算这两个字符串的相似度了。显然,它们最大的距离就是 这两个字符串的长度的大的那个长度。
资料显示,一般,将两个字符串的相似度定义为: 1-它们的距离/这两个字符串长度的最大值

算法实现

  mfc中Edit Distance算法的实现
[cpp]  view plain copy print ?
  1. float CMy0121124829Dlg::Similarity(CString string_1, CString string_2)  
  2. {  
  3.     int m = string_1.GetLength();  
  4.     int n = string_2.GetLength();  
  5.     int** different;  
  6.     try  
  7.     {  
  8.         different  = new int*[m+1];  
  9.         for (int i=0; i<=m; i++)  
  10.         {  
  11.             different[i] = new int[n+1];  
  12.         }   
  13.     }  
  14.     catch (const std::bad_alloc& e)  
  15.     {  
  16.         MessageBox(_T("内存不足,请重启程序后再试!"));  
  17.     }  
  18.       
  19.       
  20.     for (int i = 0; i <= m; i++) {   
  21.         different[i][0] = i;  
  22.     }   
  23.     for (int i = 0; i <= n; i++) {   
  24.         different[0][i] = i;   
  25.     }   
  26.     int temp;   
  27.     for (int i = 1; i <= m; i++){  
  28.   
  29.         for (int j = 1; j <= n; j++){   
  30.             if (string_1[i - 1] == string_2[j - 1]) {  
  31.                 temp = 0;   
  32.             }  
  33.             else {   
  34.                 temp = 1;   
  35.             }   
  36.             different[i][j] = Min_in_three(different[i - 1][j - 1] + temp, different[i][j - 1] + 1, different[i - 1][j] + 1);   
  37.         }   
  38.     }   
  39.     int dif = different[m][n];  
  40.     for (int i=0; i<=m; i++)  
  41.     {  
  42.         delete different[i];  
  43.     }   
  44.     delete different;  
  45.     return 1 - (float)dif/ ((string_1.GetLength()>string_2.GetLength()?string_1.GetLength(): string_2.GetLength()));  
  46. }  

你可能感兴趣的:(ACM)