Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139010
  • 博文数量: 94
  • 博客积分: 1572
  • 博客等级: 上尉
  • 技术积分: 925
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-04 00:03
文章分类

全部博文(94)

文章存档

2011年(94)

我的朋友

分类: C/C++

2011-04-07 14:38:45

LD算法就是自然语言处理(NLP)里的“编辑距离”算法。俄国科学家Levenshtein提出的,故又叫Levenshtein Distance (LD算法)。

【定义】设A和B是两个字符串。将字符串A转换为字符串B所用的最少字符操作数称为字符串A到字符串B的编辑距离。( 这里所说的字符操作包括:删除一个字符,插入一个字符,修改一个字符)

如果有人想看具体算法的描述还是自己去搜吧。我搜到的算法描述大部分是鸟语,而且下面的例子代码无数错,看了2天才写了个标准C的程序,贴出来晒晒。代码最后我加了个小应用来实现了简单的串相似度比较。代码加了注释,应该不难理解。为了篇幅小,我改了下代码排版和代码风格,推荐下载源码用编辑环境看,着色后可读性才强。

  1. #include "stdio.h"
  2. #include "malloc.h"
  3. #include "string.h"

  4. #define MAX(a,b) ((a)>(b)?(a):(b))

  5. void matrix_print(char *matrix, int row, int col)
  6. {
  7.     int i, j;
  8.     for(i=0; i<row; i++) {
  9.     for(j=0; j<col; j++) {
  10.          printf("%4.2d", matrix[i*col+j]);
  11. }
  12.      printf("\n");
  13. }
  14. }
  15. char matrix_value(char left, char top, char top_left, int cost)
  16. {
  17.     char ret = left<top?left:top;
  18.     return ret<top_left?ret+1:top_left+(char)cost;
  19. }

  20. int main()
  21. {
  22.     char *matrix, str1[255], str2[255];
  23.     int row, col, i, j, dis;
  24.     double sim;

  25.     printf("please input str1: ");
  26.     scanf("%s", str1);
  27.     printf("please input str2: ");
  28.     scanf("%s", str2);

  29.     /* 矩阵要比行列各多一来存储矩阵行列序号 */
  30.     row = strlen(str1) + 1;
  31.     col = strlen(str2) + 1;
  32.     matrix = (char*) malloc(col*row); /* 申请空间 */

  33.     /* 初始化首行、首列 */
  34.     for(i=0; i<row; i++) matrix[i*col] = i;
  35.     for(j=0; j<col; j++) matrix[j] = j;

  36.     /*
  37.     * 根据算法填充矩阵: 当字符相同时cost=0, 否则cost=1.
  38.      * 也就是代码中的 !(str1[i-1]==str2[j-1])
  39.      * 取待填值(val)位置的3个邻居left,top,top-left的值来进行比较,
  40.      * 取最小值(min)。当 left或top 为最小值时, val=min+1.
  41.      * 当 top-left 为最小值时, val=min+cost.
  42.      */
  43.     for(i=1; i<row; i++) {
  44.         for(j=1; j<col; j++)
  45.             matrix[i*col+j] = matrix_value(matrix[i*col+j-1],
  46.                                            matrix[(i-1)*col+j],
  47.                                            matrix[(i-1)*col+j-1],
  48.                                            !(str1[i-1]==str2[j-1]));
  49.     }
  50.     matrix_print(matrix, row, col);/* 打印矩阵 */
  51.     dis = matrix[(row*col - 1];/*矩阵最后的格子就是“编辑距离” */
  52.     printf("distance = %d\n", dis);

  53.     /*
  54.     * 小应用: 使用“编辑距离” 来算2个串的相似度。
  55.      * 可以根据自己需要设计不同的算法,我就是简单的除以了下长串。
  56.      */
  57.     sim = 1 - ((double)dis/(double)MAX(row-1, col-1));
  58.     printf("similar = %f\n", sim);
  59.     free(matrix);
  60. return 0;
  61. }
阅读(1016) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~