• 最小编辑距离


    概念

    编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
    例如将kitten一字转成sitting:
    sitten (k→s)
    sittin (e→i)
    sitting (→g)
    俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
     
    算法
    动态规划经常被用来作为这个问题的解决手段之一。
    具体步骤是:
    1. 建立个m*n的矩阵matrix,其中m=len(a)+1n=len(b)+1。这样,二维数组的范围就是 matrix[0...n-1][0...m-1]了。
    2. 给matrix[0][0...m-1]赋值为0...m-1matrix[0...n-1][0]赋值为0...n-1
    3. 遍历matrix[0...n-1][0...m-1]
    matrix每个元素的值都为:
    minleft{egin{array}{lll}matrix[i-1][j]+INSERT\_COST \matrix[i][j-1]+DELETE\_COST\matrix[i-1][j-1]+SUBSTITUTE\_COST(source_i target_j)end{array} ight.
    其中,INSERT_COST,DELETE_COST 都是固定值(可以自己设定12什么的)。
    而SUBSTITUTE_COST是需要判断的。
    当source_i和target_i的值是等价的时候,SUBSTITUTE_COST就是0否则SUBSTITUTE_COST就是预定义的一个权值。
    最后matrix[n-1][m-1]的值则为两个字符串的最小编辑距离。
    改进
    当source_i和target_i的值相同时,SUBSTITUTE_COST的值就是0,必然是最小值。所以首先判断两字符是否相等,若相等则直接判定matrix[i][j]=matrix[i-1][j-1],判断下个。这样可以省很多计算。
     
    伪代码:
    整数 Levenshtein距离(字符串 str1[1..m], 字符串 str2[1..n])
    //声明变量, d[i , j]用于记录str1[1...i]与str2[1..j]的Levenshtein距离
    int d[0..m, 0..n]
    //初始化
    for i from 0 to m
    d[i, 0] := i
    for j from 0 to n
    d[0, j] := j
    //用动态规划方法计算Levenshtein距离
    for i from 1 to m
    for j from 1 to n
    {
    //计算替换操作的代价,如果两个字符相同,则替换操作代价为0,否则为1
    if str1[i]== str2[j] then cost := 0
    else cost := 1
    //d[i,j]的Levenshtein距离,可以有
    d[i, j] := minimum(
    d[i-1, j] + 1,  //在str1上i-1位置插入字符(或者在str2上j位置删除字符)
    d[i, j-1] + 1,  //在str1上i位置删除字符(或者在str2上j-1位置插入字符)
    d[i-1, j-1] + cost // 替换操作
    )
     
    }
    //返回d[m, n]
    return d[m, n]
    wikisource上有不同的编程语言的版本。
     
    java代码实现
    package com.mzule.al;
    
    public class LevenshteinDistance {
    
        public double distance(String w1,String w2){
            double[][] m = new double[w1.length()+1][w2.length()+1];
            for(int i=0;i<m.length;i++){
                m[i][0]=i;
            }
            for(int i=0;i<m[0].length;i++){
                m[0][i]=i;
            }
            for(int i=1;i<m.length;i++){
                for(int j=1;j<m[0].length;j++){
                    m[i][j] = min(m[i][j-1]+1,m[i-1][j]+1,m[i-1][j-1]+cost(w1.charAt(i-1),w2.charAt(j-1)));
                }
            }
            return m[w1.length()][w2.length()];
        }
    
        protected double cost(char c1,char c2) {
            return c1==c2?0:1;
        }
    
        protected double min(double i, double j, double k) {
            double t = i<j?i:j;
            return t<k?t:k;
        }
        
    }
    

      测试代码:

    public static void main(String[] args) {
        double d = new LevenshteinDistance().distance("Lavensting", "Levenshtein");
        System.out.println(d);
    }
    

      来源:http://www.cnblogs.com/codeplus/p/3392232.html

           参考文章:http://blog.csdn.net/ac540101928/article/details/52786435

  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/tibetanmastiff/p/3738489.html
Copyright © 2020-2023  润新知