编辑距离LCS算法详解:Levenshtein Distance算法计算两个字符串的相似度

  • 最近研究一个两个字符串相识度的问题,结果发现了Levenshtein distance 算法,最早由俄国人发现,算法介绍可自行百度。仔细研究后发现其核心思想与动态规划极其相似,证明过程和实现细节可参考《算法导论》求最长字串的LCS这一章。这个在我的博客里也有记载。

    Levenshtein Distance,<span class="wp_keywordlink_affiliate">编辑距离算法,是指从字符串A变成字符串B,所需的最少编辑(增,删,插入)次数。应用也相当广泛,这里我们用来求解两个字符串的相似度。


    【例子】假设现在有源串“jary”与目标串“jerry”,求源串到目标串的<span class="wp_keywordlink_affiliate">编辑距离。

    图解过程如下:

    step 1:初始化如下矩阵

    \

    step 2:从源串的第一个字符(“j”)开始,从上至下与目标串进行对比

    \

    如果两个字符相等,则在从此位置的左,上,左上三个位置中取出最小的值;若不等,则在从此位置的左,上,左上三个位置中取出最小的值再加上1;

    第一次,源串第一个字符“j” 与目标串的“j”对比,左,上,左上三个位置中取出最小的值0,因为两字符相等,所以加上0;接着,依次对比“j”→“e”,“j”→“r”,“j”→“r”,,“j”→“y” 到扫描完目标串。

    \

    step 3:遍历整个源串与目标串对比:

    \

    \

    step 4:扫描完最后一列,则最后一个为最短编辑距离

    \

    求出编辑距离,那么两个字符串的相似度 Similarity = (Max(x,y) - Levenshtein)/Max(x,y),其中 x,y 为源串和目标串的长度。

    C#实现代码如下:


    01. public static int LevenshteinDistance(string source, string target)
    02. {
    03. int cell = source.Length;
    04. int row = target.Length;
    05. if (cell == 0) {
    06. return row;
    07. }
    08. if (row == 0) {
    09. return cell;
    10. }
    11. int[, ] matrix = new int[row + 1, cell + 1];
    12. for (var i = 0; i <= cell; i++) {
    13. matrix[0, i] = i;
    14. }
    15. for (var j = 1; j <= row; j++) {
    16. matrix[j, 0] = j;
    17. }
    18. var tmp = 0;
    19. for (var k = 0; k < row; k++) {
    20. for (var l = 0; l < cell; l++) {
    21. if (source[l].Equals(target[k])) tmp = 0;
    22. else tmp = 1;
    23. matrix[k + 1, l + 1] = Math.Min(Math.Min(matrix[k, l] + tmp, matrix[k + 1, l]), matrix[k, l + 1] + 1);
    24. }
    25. }
    26. return matrix[row, cell];
    27. }
    28.  
    29. public static float StringSimilarity(string source, string target)
    30. {
    31. var ld = LevenshteinDistance(source, target);
    32. var maxLength = Math.Max(source.Length, target.Length);
    33. return (float)(maxLength - ld) / maxLength;
    34. }

    希望对一些朋友有用。

    其实算法和结果知道了。我还是没搞明白为什么这样做可以计算得到相似度 。有更厉害的朋友欢迎指正。感谢博客园的兄弟。里面的大牛就是多,转自http://www.cnblogs.com/three-zone/archive/2013/06/06/LevenshteinDistance.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值