编辑距离问题
来源:互联网 发布:温州两家人 知乎 编辑:程序博客网 时间:2024/06/08 09:12
问题描述
字符串的编辑距离也被称为距Levenshtein距离(Levenshtein Distance),属于经典算法,常用方法使用递归,更好的方法是使用动态规划算法,以避免出现重叠子问题的反复计算,减少系统开销。
《编程之美》一书中3.3节中计算两个字符串的相似度,归根到底也是要求两个字符串的距离,其中问题是这样提出的:
许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
- 修改一个字符(如把”a”替换为”b”);
- 增加一个字符(如把”abdd”变为”aebdd”);
删除一个字符(如把”travelling”变为”traveling”);
比如,对于”abcdefg”和”abcdef”两个字符串来说,我们认为可以通过增加/减少一个”g”的方式来达到目的。上面的两种方案,都仅需要一 次 。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于”距离+1”的倒数。也就是说,”abcdefg”和”abcdef”的距离为1,相似度 为1/2=0.5。给定任意两个字符串,你是否能写出一个算法来计算它们的相似度呢?
其实这个问题的关键是要求两个字符串的编辑距离。
例如 将kitten一字转成sitting:
sitten (k→s)
- sittin (e→i)
- sitting (→g)
俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
编辑距离问题:找出字符串的编辑距离,即把一个字符串s1最少经过多少步操作变成编程字符串s2,操作有三种,添加一个字符,删除一个字符,修改一个字符。
假定dist(str1,str2)表示字符串从str1变换到str2的编辑距离,有以下四种情况:
用null表示字符串为空的情况
- dist(null,null)=0;
- dist(null,str2)=strlen(str2);
- dist(str1,null)=strlen(str1);
dist(str1,str2)
假定要求解dist(str1+char1,str2+char2),分三种情况1. 如果str1+char能够直接转换成str2,这是我们只需要插入char2即可,也就是说dist(str1+char1,str2+char2)=dist(str1+char1,str2)+12. 如果str1可以直接转成str2+char2,这是我们只需要删去char1即可,也就是说,dist(str1+char1,str2+char2)=dist(str1,str2+char2)+13. 如果str1可以直接转变成str2,也分两种情况 - 如果char1等于char2,不需要任何操作,即dist(str1+char1,str2+char2)=dist(str1,str2) - 如果char1不等于char2,把char1换成char2即可,dist(str1+char1,str2+char2)=dist(str1,str2)+1
取上面的三种情况的最小值即可。
那我们如何实现呢?设第一个字符串a的长度为m,第二个字符串b的长度为n,为了方便,我们设一个二维数组dist[n+1][m+1]
,dist[i][j]
表示字符串a前j个字符串变化到字符串b前j个字符串的编辑距离,这里是不是有点混乱,继续往下看:
根据上面分情况分析,我们可以写出如下动态公式:
- if (i == 0 && j == 0)edit[i][j] = 0;
- if (i == 0 && j > 0)edit[i][j] = j;
- if (i > 0 && j == 0)edit[i][j] = i;
- if (i >=1 && j >= 1)
int k = b[i] == a[j] ? 0 : 1;
edit[i][j] = min(edit[i - 1][j]+1, edit[i][j - 1] + 1, edit[i - 1][ j - 1] + k);
比如说字符串a=”fxpimu”,b=”xwrs”;a.length()=6,b.length()=4;即m=7,n=4;定义二维数组为dist[5][7]
,运算结果如下
所以字符串a到字符串b的最短编辑距离为5
代码如下:
#include "stdafx.h"#include<iostream>#include<vector>#include<string>using namespace std;int min(int A, int B, int C) { if (B < A) A = B; if (C < A) A = C; return A;}int main(){ int dist[6][8]; string a = "fxpimu"; string b = "xwrs"; a = " " + a; b = " " + b; for (int i = 0; i <=b.size(); i++) { for (int j = 0; j <=a.size(); j++) { if (i == 0 && j == 0)dist[i][j] = 0; else if (i == 0 && j > 0)dist[i][j] = j; else if (i > 0 && j == 0)dist[i][j] = i; else if(i>=1&&j>=1){ int k = (b[i] == a[j] ? 0 : 1); dist[i][j] = min(dist[i - 1][j]+1, dist[i][j - 1] + 1, dist[i - 1][ j - 1] + k); } } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 7; j++) { printf("%d ", dist[i][j]); } printf("\n"); } printf("编辑距离为%d",dist[b.size()][a.size()]); return 0;}
参考文章:http://www.cnblogs.com/jiabei521/p/3353390.html
- 编辑距离问题
- 【dp】编辑距离问题
- 王晓东 编辑距离问题
- 编辑距离问题 dp
- 编辑距离问题
- 王晓东 编辑距离问题
- 编辑距离问题
- 编辑距离问题
- 编辑距离问题(1)
- 编辑距离问题
- DP_编辑距离问题
- 编辑距离问题(1)
- 编辑距离问题
- 编辑距离问题
- 编辑距离问题
- 编辑距离问题
- dp 编辑距离问题
- 编辑距离问题
- python_pandas_20171104
- scramble-string Java code
- 文章标题
- malloc,alloc,realloc之间的相似与区别
- 图片上传服务器-回显
- 编辑距离问题
- day19笔记
- activemq的使用
- 移动端viewport的理解
- kmp算法
- 【视频编码格式】全面解析
- day20笔记
- 堆排序
- mysql sql语句大全