现在的位置: 首页 > 综合 > 正文

最小编辑距离(Minimum edit distance)

2018年02月20日 ⁄ 综合 ⁄ 共 1767字 ⁄ 字号 评论关闭

最小编辑距离是计算欧式距离的一种方法,可以被用于计算文本的相似性以及用于文本纠错,因为这个概念是俄罗斯科学家 Vladimir Levenshtein 在1965年提出来的,所以编辑距离又称为Levenshtein距离。

简单的理解就是将一个字符串转换到另一个字符串所需要的代价(cost),付出的代价越少表示两个字符串越相似,编辑距离越小,从一个字符串转换到另一个字符串简单的归纳可以有以下几种操作,1、删除(delete)2、插入(insert)3、修改(update),其中删除和插入的代价可以认为是等价的。

我们定于的cost如下:i,j分别是字符串中字符的index,cost是相应的代价

if i == 0 且 j == 0,cost(i, j) = 0
if i == 0 且 j > 0,cost(i, j) = j 表示删除字符需要的代价
if i > 0 且j == 0,cost(i, j) = i 表示插入字符需要的代价
if i ≥ 1  且 j ≥ 1 ,cost(i, j) == min{ cost(i-1, j) + 1, cost(i, j-1) + 1, cost(i-1, j-1) + f(i, j) },当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。
cost(i-1, j) + 1 是通过删除字符来满足相等条件的代价
cost(i, j-1) + 1 是通过插入相应字符来满足相等条件的代价
cost(i-1, j-1) + f(i, j) 是通过变换字符来满足条件的代价, f(i, j)是变换字符的代价
其实上面的公式就是动态规划的转化公式
cost[i][j] = min(cost(i-1, j) + 1,cost(i, j-1) + 1, cost(i-1, j-1) + f(i, j))

#include <stdio.h>
#include <string>
#include <iostream>
#include <string.h>
#include <stdlib.h>

int edit(const char *str1,const char* str2){
    int min_distance = 0;
    if(str1 == NULL || str2 == NULL)
        return 0;
    int len1 = strlen(str1) + 1;
    int len2 = strlen(str2) + 1;
    int **distance = (int **)malloc(sizeof(int *) * len1);
    for(int i= 0; i < len1; i++){
        distance[i] = (int *)malloc(sizeof(int) * len2);
    }
    for(int i = 0; i< len1; i++){
        distance[i][0] = i;
    }

    for(int i =0; i < len2; i++){
        distance[0][i] = i;
    }
    for(int i = 1; i < len1; i++){
        for(int j = 1;j < len2; j++){
            int tmp = std::min(distance[i-1][j] + 1, distance[i][j-1] + 1);
            int d;
            if(str1[i - 1] == str2[j - 1]){
                d = 0;
            }else{
                d = 2;
            }
            distance[i][j] = std::min(tmp, distance[i-1][j-1] + d);
        }
    }
    printf("edit distance:%d\n", distance[len1 -1][len2 -1]);
    min_distance = distance[len1-1][len2-1];
    for(int i = 0; i < len1; i++){
        for(int j = 0;j < len2; j++){
           printf("%d ", distance[i][j]);
        }
        printf("\n");
    }
    for(int i = 0; i < len1; i++){
        free(distance[i]);
    }
    free(distance);
    return min_distance;
}

int main(int argc, char* argv[]){
    if(argc != 3){
        printf("%s in1 in2\n", argv[0]);
        return 1; 
    }
    edit(argv[1], argv[2]);
    return 0;
}

./edit_distance adace aaace

0 1 2 3 4 5 
1 0 1 2 3 4 
2 1 2 3 4 5 
3 2 1 2 3 4 
4 3 2 3 2 3 
5 4 3 4 3 2 

以上是计算过程中编辑距离的演变过程

抱歉!评论已关闭.