字符串相似度算法 levenshtein distance 编辑距离算法

参考:http://www.merriampark.com/ld.htm#WHATIS
http://en.wikipedia.org/wiki/Levenshtein_distance
 
    * Java
    * C++
    * Visual Basic
    * Python

Java代码 复制代码  收藏代码
  1. Java   
  2.   
  3. public class Distance {   
  4.   
  5.   //****************************   
  6.   // Get minimum of three values   
  7.   //****************************   
  8.   
  9.   private int Minimum (int a, int b, int c) {   
  10.   int mi;   
  11.   
  12.     mi = a;   
  13.     if (b < mi) {   
  14.       mi = b;   
  15.     }   
  16.     if (c < mi) {   
  17.       mi = c;   
  18.     }   
  19.     return mi;   
  20.   
  21.   }   
  22.   
  23.   //*****************************   
  24.   // Compute Levenshtein distance   
  25.   //*****************************   
  26.   
  27.   public int LD (String s, String t) {   
  28.   int d[][]; // matrix   
  29.   int n; // length of s   
  30.   int m; // length of t   
  31.   int i; // iterates through s   
  32.   int j; // iterates through t   
  33.   char s_i; // ith character of s   
  34.   char t_j; // jth character of t   
  35.   int cost; // cost   
  36.   
  37.     // Step 1   
  38.   
  39.     n = s.length ();   
  40.     m = t.length ();   
  41.     if (n == 0) {   
  42.       return m;   
  43.     }   
  44.     if (m == 0) {   
  45.       return n;   
  46.     }   
  47.     d = new int[n+1][m+1];   
  48.   
  49.     // Step 2   
  50.   
  51.     for (i = 0; i <= n; i++) {   
  52.       d[i][0] = i;   
  53.     }   
  54.   
  55.     for (j = 0; j <= m; j++) {   
  56.       d[0][j] = j;   
  57.     }   
  58.   
  59.     // Step 3   
  60.   
  61.     for (i = 1; i <= n; i++) {   
  62.   
  63.       s_i = s.charAt (i - 1);   
  64.   
  65.       // Step 4   
  66.   
  67.       for (j = 1; j <= m; j++) {   
  68.   
  69.         t_j = t.charAt (j - 1);   
  70.   
  71.         // Step 5   
  72.   
  73.         if (s_i == t_j) {   
  74.           cost = 0;   
  75.         }   
  76.         else {   
  77.           cost = 1;   
  78.         }   
  79.   
  80.         // Step 6   
  81.   
  82.         d[i][j] = Minimum (d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);   
  83.   
  84.       }   
  85.   
  86.     }   
  87.   
  88.     // Step 7   
  89.   
  90.     return d[n][m];   
  91.   
  92.   }   
  93.   
  94. }   
  95.   
  96. C++   
  97.   
  98. In C++, the size of an array must be a constant, and this code fragment causes an error at compile time:   
  99.   
  100. int sz = 5;   
  101. int arr[sz];   
  102.   
  103. This limitation makes the following C++ code slightly more complicated than it would be if the matrix could simply be declared as a two-dimensional array, with a size determined at run-time.   
  104.   
  105. In C++ it's more idiomatic to use the System Template Library's vector class, as Anders Sewerin Johansen has done in an alternative C++ implementation.   
  106.   
  107. Here is the definition of the class (distance.h):   
  108.   
  109. class Distance   
  110. {   
  111.   public:   
  112.     int LD (char const *s, char const *t);   
  113.   private:   
  114.     int Minimum (int a, int b, int c);   
  115.     int *GetCellPointer (int *pOrigin, int col, int row, int nCols);   
  116.     int GetAt (int *pOrigin, int col, int row, int nCols);   
  117.     void PutAt (int *pOrigin, int col, int row, int nCols, int x);   
  118. };    
  119.   
  120. Here is the implementation of the class (distance.cpp):   
  121.   
  122. #include "distance.h"  
  123. #include <string.h>   
  124. #include <malloc.h>   
  125.   
  126. //****************************   
  127. // Get minimum of three values   
  128. //****************************   
  129.   
  130. int Distance::Minimum (int a, int b, int c)   
  131. {   
  132. int mi;   
  133.   
  134.   mi = a;   
  135.   if (b < mi) {   
  136.     mi = b;   
  137.   }   
  138.   if (c < mi) {   
  139.     mi = c;   
  140.   }   
  141.   return mi;   
  142.   
  143. }   
  144.   
  145. //**************************************************   
  146. // Get a pointer to the specified cell of the matrix   
  147. //**************************************************    
  148.   
  149. int *Distance::GetCellPointer (int *pOrigin, int col, int row, int nCols)   
  150. {   
  151.   return pOrigin + col + (row * (nCols + 1));   
  152. }   
  153.   
  154. //*****************************************************   
  155. // Get the contents of the specified cell in the matrix    
  156. //*****************************************************   
  157.   
  158. int Distance::GetAt (int *pOrigin, int col, int row, int nCols)   
  159. {   
  160. int *pCell;   
  161.   
  162.   pCell = GetCellPointer (pOrigin, col, row, nCols);   
  163.   return *pCell;   
  164.   
  165. }   
  166.   
  167. //*******************************************************   
  168. // Fill the specified cell in the matrix with the value x   
  169. //*******************************************************   
  170.   
  171. void Distance::PutAt (int *pOrigin, int col, int row, int nCols, int x)   
  172. {   
  173. int *pCell;   
  174.   
  175.   pCell = GetCellPointer (pOrigin, col, row, nCols);   
  176.   *pCell = x;   
  177.   
  178. }   
  179.   
  180. //*****************************   
  181. // Compute Levenshtein distance   
  182. //*****************************   
  183.   
  184. int Distance::LD (char const *s, char const *t)   
  185. {   
  186. int *d; // pointer to matrix   
  187. int n; // length of s   
  188. int m; // length of t   
  189. int i; // iterates through s   
  190. int j; // iterates through t   
  191. char s_i; // ith character of s   
  192. char t_j; // jth character of t   
  193. int cost; // cost   
  194. int result; // result   
  195. int cell; // contents of target cell   
  196. int above; // contents of cell immediately above   
  197. int left; // contents of cell immediately to left   
  198. int diag; // contents of cell immediately above and to left   
  199. int sz; // number of cells in matrix   
  200.   
  201.   // Step 1    
  202.   
  203.   n = strlen (s);   
  204.   m = strlen (t);   
  205.   if (n == 0) {   
  206.     return m;   
  207.   }   
  208.   if (m == 0) {   
  209.     return n;   
  210.   }   
  211.   sz = (n+1) * (m+1) * sizeof (int);   
  212.   d = (int *) malloc (sz);   
  213.   
  214.   // Step 2   
  215.   
  216.   for (i = 0; i <= n; i++) {   
  217.     PutAt (d, i, 0, n, i);   
  218.   }   
  219.   
  220.   for (j = 0; j <= m; j++) {   
  221.     PutAt (d, 0, j, n, j);   
  222.   }   
  223.   
  224.   // Step 3   
  225.   
  226.   for (i = 1; i <= n; i++) {   
  227.   
  228.     s_i = s[i-1];   
  229.   
  230.     // Step 4   
  231.   
  232.     for (j = 1; j <= m; j++) {   
  233.   
  234.       t_j = t[j-1];   
  235.   
  236.       // Step 5   
  237.   
  238.       if (s_i == t_j) {   
  239.         cost = 0;   
  240.       }   
  241.       else {   
  242.         cost = 1;   
  243.       }   
  244.   
  245.       // Step 6    
  246.   
  247.       above = GetAt (d,i-1,j, n);   
  248.       left = GetAt (d,i, j-1, n);   
  249.       diag = GetAt (d, i-1,j-1, n);   
  250.       cell = Minimum (above + 1, left + 1, diag + cost);   
  251.       PutAt (d, i, j, n, cell);   
  252.     }   
  253.   }   
  254.   
  255.   // Step 7   
  256.   
  257.   result = GetAt (d, n, m, n);   
  258.   free (d);   
  259.   return result;   
  260.        
  261. }   
  262.   
  263. Visual Basic   
  264.   
  265. '*******************************   
  266. '*** Get minimum of three values   
  267. '*******************************   
  268.   
  269. Private Function Minimum(ByVal a As Integer, _   
  270.                          ByVal b As Integer, _   
  271.                          ByVal c As Integer) As Integer   
  272. Dim mi As Integer   
  273.                              
  274.   mi = a   
  275.   If b < mi Then   
  276.     mi = b   
  277.   End If   
  278.   If c < mi Then   
  279.     mi = c   
  280.   End If   
  281.      
  282.   Minimum = mi   
  283.                              
  284. End Function   
  285.   
  286. '********************************   
  287. '*** Compute Levenshtein Distance   
  288. '********************************   
  289.   
  290. Public Function LD(ByVal s As String, ByVal t As String) As Integer   
  291. Dim d() As Integer ' matrix   
  292. Dim m As Integer ' length of t   
  293. Dim n As Integer ' length of s   
  294. Dim i As Integer ' iterates through s   
  295. Dim j As Integer ' iterates through t   
  296. Dim s_i As String ' ith character of s   
  297. Dim t_j As String ' jth character of t   
  298. Dim cost As Integer ' cost   
  299.      
  300.   ' Step 1  
  301.      
  302.   n = Len(s)   
  303.   m = Len(t)   
  304.   If n = 0 Then   
  305.     LD = m   
  306.     Exit Function   
  307.   End If    
  308.   If m = 0 Then   
  309.     LD = n   
  310.     Exit Function   
  311.   End If    
  312.   ReDim d(0 To n, 0 To m) As Integer   
  313.      
  314.   ' Step 2  
  315.      
  316.   For i = 0 To n   
  317.     d(i, 0) = i   
  318.   Next i   
  319.      
  320.   For j = 0 To m   
  321.     d(0, j) = j   
  322.   Next j   
  323.   
  324.   ' Step 3  
  325.   
  326.   For i = 1 To n   
  327.        
  328.     s_i = Mid$(s, i, 1)   
  329.        
  330.     ' Step 4  
  331.        
  332.     For j = 1 To m   
  333.          
  334.       t_j = Mid$(t, j, 1)   
  335.          
  336.       ' Step 5  
  337.          
  338.       If s_i = t_j Then   
  339.         cost = 0  
  340.       Else   
  341.         cost = 1  
  342.       End If   
  343.          
  344.       ' Step 6  
  345.          
  346.       d(i, j) = Minimum(d(i - 1, j) + 1, d(i, j - 1) + 1, d(i - 1, j - 1) + cost)   
  347.        
  348.     Next j   
  349.        
  350.   Next i   
  351.      
  352.   ' Step 7  
  353.      
  354.   LD = d(n, m)   
  355.   Erase d   
  356.   
  357. End Function  
Java

public class Distance {

  //****************************
  // Get minimum of three values
  //****************************

  private int Minimum (int a, int b, int c) {
  int mi;

    mi = a;
    if (b < mi) {
      mi = b;
    }
    if (c < mi) {
      mi = c;
    }
    return mi;

  }

  //*****************************
  // Compute Levenshtein distance
  //*****************************

  public int LD (String s, String t) {
  int d[][]; // matrix
  int n; // length of s
  int m; // length of t
  int i; // iterates through s
  int j; // iterates through t
  char s_i; // ith character of s
  char t_j; // jth character of t
  int cost; // cost

    // Step 1

    n = s.length ();
    m = t.length ();
    if (n == 0) {
      return m;
    }
    if (m == 0) {
      return n;
    }
    d = new int[n+1][m+1];

    // Step 2

    for (i = 0; i <= n; i++) {
      d[i][0] = i;
    }

    for (j = 0; j <= m; j++) {
      d[0][j] = j;
    }

    // Step 3

    for (i = 1; i <= n; i++) {

      s_i = s.charAt (i - 1);

      // Step 4

      for (j = 1; j <= m; j++) {

        t_j = t.charAt (j - 1);

        // Step 5

        if (s_i == t_j) {
          cost = 0;
        }
        else {
          cost = 1;
        }

        // Step 6

        d[i][j] = Minimum (d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);

      }

    }

    // Step 7

    return d[n][m];

  }

}

C++

In C++, the size of an array must be a constant, and this code fragment causes an error at compile time:

int sz = 5;
int arr[sz];

This limitation makes the following C++ code slightly more complicated than it would be if the matrix could simply be declared as a two-dimensional array, with a size determined at run-time.

In C++ it's more idiomatic to use the System Template Library's vector class, as Anders Sewerin Johansen has done in an alternative C++ implementation.

Here is the definition of the class (distance.h):

class Distance
{
  public:
    int LD (char const *s, char const *t);
  private:
    int Minimum (int a, int b, int c);
    int *GetCellPointer (int *pOrigin, int col, int row, int nCols);
    int GetAt (int *pOrigin, int col, int row, int nCols);
    void PutAt (int *pOrigin, int col, int row, int nCols, int x);
}; 

Here is the implementation of the class (distance.cpp):

#include "distance.h"
#include <string.h>
#include <malloc.h>

//****************************
// Get minimum of three values
//****************************

int Distance::Minimum (int a, int b, int c)
{
int mi;

  mi = a;
  if (b < mi) {
    mi = b;
  }
  if (c < mi) {
    mi = c;
  }
  return mi;

}

//**************************************************
// Get a pointer to the specified cell of the matrix
//************************************************** 

int *Distance::GetCellPointer (int *pOrigin, int col, int row, int nCols)
{
  return pOrigin + col + (row * (nCols + 1));
}

//*****************************************************
// Get the contents of the specified cell in the matrix 
//*****************************************************

int Distance::GetAt (int *pOrigin, int col, int row, int nCols)
{
int *pCell;

  pCell = GetCellPointer (pOrigin, col, row, nCols);
  return *pCell;

}

//*******************************************************
// Fill the specified cell in the matrix with the value x
//*******************************************************

void Distance::PutAt (int *pOrigin, int col, int row, int nCols, int x)
{
int *pCell;

  pCell = GetCellPointer (pOrigin, col, row, nCols);
  *pCell = x;

}

//*****************************
// Compute Levenshtein distance
//*****************************

int Distance::LD (char const *s, char const *t)
{
int *d; // pointer to matrix
int n; // length of s
int m; // length of t
int i; // iterates through s
int j; // iterates through t
char s_i; // ith character of s
char t_j; // jth character of t
int cost; // cost
int result; // result
int cell; // contents of target cell
int above; // contents of cell immediately above
int left; // contents of cell immediately to left
int diag; // contents of cell immediately above and to left
int sz; // number of cells in matrix

  // Step 1	

  n = strlen (s);
  m = strlen (t);
  if (n == 0) {
    return m;
  }
  if (m == 0) {
    return n;
  }
  sz = (n+1) * (m+1) * sizeof (int);
  d = (int *) malloc (sz);

  // Step 2

  for (i = 0; i <= n; i++) {
    PutAt (d, i, 0, n, i);
  }

  for (j = 0; j <= m; j++) {
    PutAt (d, 0, j, n, j);
  }

  // Step 3

  for (i = 1; i <= n; i++) {

    s_i = s[i-1];

    // Step 4

    for (j = 1; j <= m; j++) {

      t_j = t[j-1];

      // Step 5

      if (s_i == t_j) {
        cost = 0;
      }
      else {
        cost = 1;
      }

      // Step 6 

      above = GetAt (d,i-1,j, n);
      left = GetAt (d,i, j-1, n);
      diag = GetAt (d, i-1,j-1, n);
      cell = Minimum (above + 1, left + 1, diag + cost);
      PutAt (d, i, j, n, cell);
    }
  }

  // Step 7

  result = GetAt (d, n, m, n);
  free (d);
  return result;
	
}

Visual Basic

'*******************************
'*** Get minimum of three values
'*******************************

Private Function Minimum(ByVal a As Integer, _
                         ByVal b As Integer, _
                         ByVal c As Integer) As Integer
Dim mi As Integer
                          
  mi = a
  If b < mi Then
    mi = b
  End If
  If c < mi Then
    mi = c
  End If
  
  Minimum = mi
                          
End Function

'********************************
'*** Compute Levenshtein Distance
'********************************

Public Function LD(ByVal s As String, ByVal t As String) As Integer
Dim d() As Integer ' matrix
Dim m As Integer ' length of t
Dim n As Integer ' length of s
Dim i As Integer ' iterates through s
Dim j As Integer ' iterates through t
Dim s_i As String ' ith character of s
Dim t_j As String ' jth character of t
Dim cost As Integer ' cost
  
  ' Step 1
  
  n = Len(s)
  m = Len(t)
  If n = 0 Then
    LD = m
    Exit Function
  End If 
  If m = 0 Then
    LD = n
    Exit Function
  End If 
  ReDim d(0 To n, 0 To m) As Integer
  
  ' Step 2
  
  For i = 0 To n
    d(i, 0) = i
  Next i
  
  For j = 0 To m
    d(0, j) = j
  Next j

  ' Step 3

  For i = 1 To n
    
    s_i = Mid$(s, i, 1)
    
    ' Step 4
    
    For j = 1 To m
      
      t_j = Mid$(t, j, 1)
      
      ' Step 5
      
      If s_i = t_j Then
        cost = 0
      Else
        cost = 1
      End If
      
      ' Step 6
      
      d(i, j) = Minimum(d(i - 1, j) + 1, d(i, j - 1) + 1, d(i - 1, j - 1) + cost)
    
    Next j
    
  Next i
  
  ' Step 7
  
  LD = d(n, m)
  Erase d

End Function





Python代码 复制代码  收藏代码
  1. #!/user/bin/env python   
  2. # -*- coding: utf-8 -*-   
  3.   
  4. class arithmetic():   
  5.        
  6.     def __init__(self):   
  7.         pass  
  8.     ''''' 【编辑距离算法】 【levenshtein distance】 【字符串相似度算法】 '''  
  9.     def levenshtein(self,first,second):   
  10.         if len(first) > len(second):   
  11.             first,second = second,first   
  12.         if len(first) == 0:   
  13.             return len(second)   
  14.         if len(second) == 0:   
  15.             return len(first)   
  16.         first_length = len(first) + 1  
  17.         second_length = len(second) + 1  
  18.         distance_matrix = [range(second_length) for x in range(first_length)]    
  19.         #print distance_matrix   
  20.         for i in range(1,first_length):   
  21.             for j in range(1,second_length):   
  22.                 deletion = distance_matrix[i-1][j] + 1  
  23.                 insertion = distance_matrix[i][j-1] + 1  
  24.                 substitution = distance_matrix[i-1][j-1]   
  25.                 if first[i-1] != second[j-1]:   
  26.                     substitution += 1  
  27.                 distance_matrix[i][j] = min(insertion,deletion,substitution)   
  28.         print distance_matrix   
  29.         return distance_matrix[first_length-1][second_length-1]   
  30.        
  31. if __name__ == "__main__":   
  32.     arith = arithmetic()   
  33.     print arith.levenshtein('GUMBOsdafsadfdsafsafsadfasfadsfasdfasdfs','GAMBOL00000000000dfasfasfdafsafasfasdfdsa'  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值