算法:LevenshteinDistance编辑距离:两个字符串的相似度,Java实现

编辑距离Levenshtein):两个字符之间有一个转成另一个所用的最少的编辑操作次数,操作包括:替换插入删除一个字符。 

定义:

       

原理:
首先考虑极端情况,当或长度为0时,那么需要编辑的次数就是里一个字符串的长度。

然后再考虑一般情况,此时分为三种情况:

在k个操作中,将a[1...i]转换为b[1...j-1]:例如:a(abc)    b(abcd)
在k个操作中,将a[1...i-1]转换为b[1...j]:例如:a(abc)    b(ab)
在k个操作中,将a[1...i-1]转换为b[1...j-1]:例如:a(abc)   b(abb)
针对第一种情况,只需要在a[1...i]后加上字符b[j],即可完成a[1..i]到b[1...j]的转换,总共需要的编辑次数即为k+1。

针对第二种情况,只需要在a[i]字符从a中移除,即可完成a[1..i]到b[1...j]的转换,总共需要的编辑次数即为k+1。

针对第三种情况,只需要将a[i]转换为b[j],即可完成a[1..i]到b[1...j]的转换,如果a[i]与b[i]的字符相同,则总共需要的编辑次数为k,否则即为k+1。

所以上述三种情况分别对应于插入、删除、替换操作。

为了保证将a[1..i]转换为b[1..j]的操作数总是最少的,只需要从三种情况中选择操作次数最少的情况,同理为了保证三种情况的操作数也是最小的,只需要按此逻辑进行迭代保证每一步的操作数都是最小的即可。

String left="helloword";
String right="hellowo";

 

代码:

package com.parse;

public class Test3 {

    public static void main(String args[]){
        String left="helloword";
        String right="hellowo";
        int maxLength = Math.max(left.length(), right.length());
        //计算编辑距离
        double lev = unlimitedCompare(left, right);
        System.out.println("编辑距离:"+lev);
        //计算相似度
        double levNorm = 1 - (lev / maxLength);

        System.out.println("相似度:"+levNorm);
    }

    public static int unlimitedCompare(CharSequence left, CharSequence right) {
        if (left == null || right == null) {
            throw new IllegalArgumentException("Strings must not be null");
        }

        int n = left.length();
        int m = right.length();
        //如果有一个String长度为0,则编辑长度为另一个String长度
        if (n == 0) {
            return m;
        } else if (m == 0) {
            return n;
        }

        int [][] dp = new int [n+1][m+1];   //动态规划数组
        int i;//left的索引
        int j;//right的索引

        char leftI; // left字符串第i项字符
        char rightJ; // right字符串第j项字符
        int cost;   //操作代价

        //初始化第一列
        for (i = 0; i <= n; i++)
        {
            dp[i][0] =i;
        }
        //初始化第一行
        for (j = 0; j <= m; j++)
        {
            dp[0][j] = j;
        }

        for (i = 1; i <= n; i++) {
            leftI =left.charAt(i - 1);
            for (j = 1; j <= m; j++) {
                rightJ = right.charAt(j - 1);

                //从i看是否和rightJ相同,所需要的操作代价,不同就会+1,相同为0
                cost = leftI == rightJ ? 0 : 1;
                //取dp[i - 1][j] + 1,dp[i][j-1] + 1, dp[i-1][j-1] + cost这三者中最小的
                dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j-1] + 1), dp[i-1][j-1] + cost);

            }
        }

        return dp[n][m];
    }
}

 感觉理解了?    想想下面的编辑距离为啥是2,而不是3?

String left="abroad";
String right="aboard";
String left="abroad";
String right="aboadr";

 

不理解的话,看看文章开头第一句话中的“最少”二字。 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编辑距离算法是一种用来衡量字符串之间相似度的算法,它可以计算出将一个字符串转换为另一个字符串所需的最小操作数。 编辑距离的计算使用了Levenshtein distance算法,该算法由俄罗斯数学家Vladimir Levenshtein在1965年提出。它通过插入、删除和替换字符来计算两个字符串之间的距离算法的基本思想是逐个比较字符串中的字符,当字符不相同时,可以选择进行插入、删除或替换操作,使得两个字符相等,从而减小距离。通过一系列的操作,最后可以得到两个字符串相等的情况。 在计算过程中,算法使用了一个二维矩阵来表示两个字符串之间的距离。矩阵的行表示源字符串的字符,列表示目标字符串的字符。矩阵中的每个值表示在当前位置上,通过一系列操作所需的最小距离。通过动态规划的方式,算法逐步填充矩阵,直到计算得到整个矩阵。 计算编辑距离的过程是从左上角到右下角的遍历,每一步都考虑当前位置的字符是否相等,如果相等,则跳过该字符;如果不相等,则可以选择插入、删除或替换操作,并选择最小操作数。最后,右下角的值即为两个字符串之间的编辑距离编辑距离算法可以应用于许多领域,如拼写纠正、基因序列比对等。通过计算字符串之间的相似度,可以帮助我们理解文本、数据的相似性程度,从而提供更好的数据处理与分析效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值