zoukankan      html  css  js  c++  java
  • LD算法获取字符串相似度

    一个如何识别相似语句的问题,于是上网找了找,一个叫Levenshtein Distance的算法比较简单,就写了段代码实现了一下,效果还不错。

    这个算法是一个俄国人Lvenshtein提出的,用于计算两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。次数越少,表示两个字符串相似度越高。

    用实例来讲解算法最直观,我们假设有两个字符串:test和est,需要经过以下几个步骤来获取LD值。

    1、初始化一个矩阵

    ┌──┬───────────┐ │  │test t e s t │ ├──┼───────────┤ │ est│ 0 1 2 3 4 │ │ e│ 1 x │ │ s│ 2 │ │ t│ 3 │ └──┴───────────┘

    2、计算x值

    计算x的算法为:

    取x1 = 左边的值+1 = 1+1 = 2;
    
    取x2 = 上边的值+1 = 1+1 = 2;
    
    如果横纵坐标的字符不一样,则取x3 = 左上角的值+1,否则取x3 = 左上角的值。此处由于e≠t,所以x3 = 0+1 = 1。
    
    然后得到x = min(x1, x2, x3) = 1。
    

    3、以此类推,填满矩阵,最右下角的值即为LD值

    ┌──┬───────────┐ │ │test t e s t │ ├──┼───────────┤ │ est│ 0 1 2 3 4 │ │ e│ 1 1 1 2 3 │ │ s│ 2 2 2 1 2 │ │ t│ 3 2 3 2 1 │ └──┴───────────┘

    4、计算相似度

    公式为:相似度 = 1 - (LD / 最大字符串长度)

    本例中,相似度 = 1 - (1 / 4) = 0.75,这个值介于0到1之间,值越高,表示两字符串相似度越大。

    用C#代码实现一下:

    ///


    /// 计算LD值
    ///

    /// 第一个字符串
    /// 第二个字符串
    /// LD
    public int GetLevenshteinDistince(string str1, string str2)
    {
    //初始化矩阵
    int[,] matrix = new int[str1.Length + 1, str2.Length + 1];

    //赋第一行与第一列的初值 
    for(int i = 0; i <= str1.Length; ++i) 
        matrix[i, 0] = i; 
    
    for(int i = 0; i <= str2.Length; ++i) 
        matrix[0, i] = i; 
    
    //开始填充矩阵 
    for(int i = 1; i <= str1.Length; i++) 
    { 
        for(int j = 1; j <= str2.Length; j++) 
        { 
            //左上角相同加0,否则加1 
            int addition = str1[i - 1] == str2[j - 1] ? 0 : 1; 
    
            //取三者中的最小值 
            int min = Math.Min(matrix[i - 1, j - 1] + addition, matrix[i, j - 1] + 1); 
            matrix[i, j] = Math.Min(min, matrix[i - 1, j] + 1); 
        } 
    } 
    
    //矩阵最右下角数字即是LD 
    return matrix[str1.Length, str2.Length]; 
    

    }

    ///


    /// 计算相似度
    ///

    /// 第一个字符串
    /// 第二个字符串
    /// 相似度,0-1之间
    public float ComputeSimilarity(string str1, string str2)
    {
    return 1 - (float)GetLevenshteinDistince(str1, str2) / Math.Max(str1.Length, str2.Length);
    }

  • 相关阅读:
    罗马数字转整数-算法练习
    无重复字符的最长字串-算法练习
    亲密字符串-算法刷题笔记
    0-n-1中缺失的数字-算法总结笔记
    高度检查表-算法笔记总结
    链表删除中间结点-算法练习总结
    链表中的中间结点-算法练习总结
    链表相交-算法练习总结
    多数元素-算法笔记总结
    Consul Windows集群搭建ACL Token验证
  • 原文地址:https://www.cnblogs.com/yibinboy/p/5645257.html
Copyright © 2011-2022 走看看