字符串相似度-动态规划法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/y5526046/article/details/51994348

动态规划法

  1. 算法描述
    动态规划法,是将待解决的问题分解为若干个子问题(阶段),按顺序求解子阶段的结果,并且后一阶段的决策都要依赖前一子问题。利用动态规划法求取字符相似度的过程如下:

    1. 用d[i,j]表示源字符串source[1..i]到目标target[1..j]之间的最小编辑距离,则计算d[i,j]的递推关系可以这样计算出来:
    2. 先初始化两组字符串:对source,d[i,0]=I;对target,d[0,j]=j。
      如果source[i] 等于target[j],则:
      d[i,j]=d[i,j]+0

      如果source[i] 不等于target[j],则根据插入、删除和替换三个策略,分别计算出使用三种策略得到的编辑距离,然后取最小的一个:
      d[i,j]=min(d[i,j1]+1d[i1,j]+1d[i1,j1]+1)

      其中d[i,j-1]+1 表示对source[i]执行插入操作后计算最小编辑距离;
      d[i-1,j]+1表示对source[i]执行删除操作后计算最小编辑距离 ;
      d[i-1,j-1]+1表示对source[i]替换成target[i]操作后计算最小编辑距离。
    3. d[i,j]的边界值就是source为空或target为空时所计算出的编辑距离。
  2. 算法优缺
    动态规划法计算字符串相似度,采用矩阵的方式计算编辑距离,计算过程中会遍历两个字符串的每一个字符,对其进行两两比较,时间复杂度至少为O(MN)。

  3. java实现
/**
 * 字符串工具类
 * @author Y
 *
 */
public class Str {

    /**
     * 通过动态规划算法获取两个字符串之间的相似度
     * @param source 源字符串
     * @param target 目标字符串
     * @return source与target之间的相似度
     */
    public static double getStrSimilarity(String source,String target){
        double similarity = 1 - (double) getShortestDistance(source,target) / Math.max(source.length(), target.length());       
        return similarity;
    }

    /**
     * 获取两个字符串之间的最短编辑距离
     * @param source 源字符串
     * @param target 目标字符串
     * @return source与target之间的最短编辑距离
     */
    public static int getShortestDistance(String source,String target){
        int d[][];
        int sourceLen = source.length();
        int targetLen = target.length();
        int distance; 

        // 提高效率,去除不影响正确性
        if (sourceLen == 0) return targetLen;
        if (targetLen == 0) return sourceLen;

        // 初始化矩阵
        d = new int[sourceLen + 1][targetLen + 1];
        for (int i = 0; i <= sourceLen; i++) { d[i][0] = i; }
        for (int j = 0; j <= targetLen; j++) { d[0][j] = j; }

        // 遍历比较
        for (int i = 0; i <= sourceLen - 1; i++) {
            for (int j = 0; j <= targetLen - 1; j++) {
                distance = source.charAt(i) == target.charAt(j) ? 0 : 1;
                d[i + 1][j + 1] = Math.min(Math.min(d[i][j + 1] + 1, d[i + 1][j] + 1), d[i][j] + distance);
            }
        }
        return d[sourceLen][targetLen];
    }

}

猜你喜欢

转载自blog.csdn.net/y5526046/article/details/51994348