• 字符串相似度算法(Levenshtein Distance)


    Levenshtein Distance(LD)算法是比较两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值,如果s是源字符串souce,t是目标字符串target,比较s和t是否相似,如下:

    • 如果s="test",t="test",那么LD(str1,str2) = 0。没有经过转换。

    • 如果s="test",t="tent",那么LD(str1,str2) = 1。str1的"s"转换"n",转换了一个字符,所以是1。如果它们的距离越大,说明它们越不同。

        Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。

        Levenshtein distance可以用来:

    • Spell checking(拼写检查)

    • Speech recognition(语句识别)

    • DNA analysis(DNA分析)

    • Plagiarism detection(抄袭检测)

    LD算法大概过程:

    Steps

    Step

    Description

    1

    Set n to be the length of s.
    Set m to be the length of t.
    If n = 0, return m and exit.
    If m = 0, return n and exit.
    Construct a matrix containing 0..m rows and 0..n columns.

    2

    Initialize the first row to 0..n.
    Initialize the first column to 0..m.

    3

    Examine each character of s (i from 1 to n).

    4

    Examine each character of t (j from 1 to m).

    5

    If s[i] equals t[j], the cost is 0.
    If s[i] doesn't equal t[j], the cost is 1.

    6

    Set cell d[i,j] of the matrix equal to the minimum of:
    a. The cell immediately above plus 1: d[i-1,j] + 1.
    b. The cell immediately to the left plus 1: d[i,j-1] + 1.
    c. The cell diagonally above and to the left plus the cost: d[i-1,j-1] + cost.

    7

    After the iteration steps (3, 4, 5, 6) are complete, the distance is found in cell d[n,m]


    distance头文件

    1. class Distance
    2. {
    3.   public:
    4.     int LD (char const *s, char const *t);
    5.   private:
    6.     int Minimum (int a, int b, int c);
    7.     int *GetCellPointer (int *pOrigin, int col, int row, int nCols);
    8.     int GetAt (int *pOrigin, int col, int row, int nCols);
    9.     void PutAt (int *pOrigin, int col, int row, int nCols, int x);
    10. }; 

    distance代码文件
    1. #include "distance.h"
    2. #include <string.h>
    3. #include <malloc.h>
    4. //****************************
    5. // Get minimum of three values
    6. //****************************
    7. int Distance::Minimum (int a, int b, int c)
    8. {
    9. int mi;
    10.   mi = a;
    11.   if (b < mi) {
    12.     mi = b;
    13.   }
    14.   if (c < mi) {
    15.     mi = c;
    16.   }
    17.   return mi;
    18. }
    19. //**************************************************
    20. // Get a pointer to the specified cell of the matrix
    21. //************************************************** 
    22. int *Distance::GetCellPointer (int *pOrigin, int col, int row, int nCols)
    23. {
    24.   return pOrigin + col + (row * (nCols + 1));
    25. }
    26. //*****************************************************
    27. // Get the contents of the specified cell in the matrix 
    28. //*****************************************************
    29. int Distance::GetAt (int *pOrigin, int col, int row, int nCols)
    30. {
    31. int *pCell;
    32.   pCell = GetCellPointer (pOrigin, col, row, nCols);
    33.   return *pCell;
    34. }
    35. //*******************************************************
    36. // Fill the specified cell in the matrix with the value x
    37. //*******************************************************
    38. void Distance::PutAt (int *pOrigin, int col, int row, int nCols, int x)
    39. {
    40. int *pCell;
    41.   pCell = GetCellPointer (pOrigin, col, row, nCols);
    42.   *pCell = x;
    43. }
    44. //*****************************
    45. // Compute Levenshtein distance
    46. //*****************************
    47. int Distance::LD (char const *s, char const *t)
    48. {
    49. int *d; // pointer to matrix
    50. int n; // length of s
    51. int m; // length of t
    52. int i; // iterates through s
    53. int j; // iterates through t
    54. char s_i; // ith character of s
    55. char t_j; // jth character of t
    56. int cost; // cost
    57. int result; // result
    58. int cell; // contents of target cell
    59. int above; // contents of cell immediately above
    60. int left; // contents of cell immediately to left
    61. int diag; // contents of cell immediately above and to left
    62. int sz; // number of cells in matrix
    63.   // Step 1 
    64.   n = strlen (s);
    65.   m = strlen (t);
    66.   if (n == 0) {
    67.     return m;
    68.   }
    69.   if (m == 0) {
    70.     return n;
    71.   }
    72.   sz = (n+1) * (m+1) * sizeof (int);
    73.   d = (int *) malloc (sz);
    74.   // Step 2
    75.   for (i = 0; i <= n; i++) {
    76.     PutAt (d, i, 0, n, i);
    77.   }
    78.   for (j = 0; j <= m; j++) {
    79.     PutAt (d, 0, j, n, j);
    80.   }
    81.   // Step 3
    82.   for (i = 1; i <= n; i++) {
    83.     s_i = s[i-1];
    84.     // Step 4
    85.     for (j = 1; j <= m; j++) {
    86.       t_j = t[j-1];
    87.       // Step 5
    88.       if (s_i == t_j) {
    89.         cost = 0;
    90.       }
    91.       else {
    92.         cost = 1;
    93.       }
    94.       // Step 6 
    95.       above = GetAt (d,i-1,j, n);
    96.       left = GetAt (d,i, j-1, n);
    97.       diag = GetAt (d, i-1,j-1, n);
    98.       cell = Minimum (above + 1, left + 1, diag + cost);
    99.       PutAt (d, i, j, n, cell);
    100.     }
    101.   }
    102.   // Step 7
    103.   result = GetAt (d, n, m, n);
    104.   free (d);
    105.   return result;
    106.     
    107. }
  • 相关阅读:
    多播委托和匿名方法再加上Lambda表达式
    委托
    从警察抓小偷看委托
    StringBuilder
    C#修饰符详解
    数据结构与算法之队列
    数据结构与算法之栈
    win10重复安装
    网络编程基础
    PrintPreviewControl
  • 原文地址:https://www.cnblogs.com/bayonetxxx/p/1897242.html
Copyright © 2020-2023  润新知