问题

字符串的编辑距离也被称为距Levenshtein距离(Levenshtein Distance),属于经典算法,常用方法使用递归,更好的方法是使用动态规划算法,以避免出现重叠子问题的反复计算,减少系统开销。


思考

也许我们以前遇过这样一个问题:

计算两个字符串的相似度。

关于相似度的定义,从下面这个例子了解一下:

比如,对于”abcdefg”和”abcdef”两个字符串来说,我们认为可以通过增加/减少一个”g”的方式来达到目的。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于”距离+1”的倒数。也就是说,”abcdefg”和”abcdef”的距离为1,相似度 为1/2=0.5。给定任意两个字符串,你是否能写出一个算法来计算它们的相似度呢?(其实这个问题的关键是要求两个字符串的编辑距离。)

这个问题其实是由俄罗斯科学家Vladimir Levenshtein在1965年提出的。


分析

*先考虑一些特殊情况:

d(null, B) = strlen(B);
d(A, null) = strlen(A);
d(A, B) = 0 当且仅当 A = B.

*再考虑一般情况下的 d(A, B)

运用动态规划求出递归方程,将原问题分解为若干个子问题进行求最优解,而后得出原问题的最优解,采用“填表的方法”。
设计步骤:对每个子问题只求解一次,将其结果保存在一张表(构造一个行数为n+1 列数为 m+1 的矩阵 , 用来保存完成某个转换需要执行的最少操作的次数, 其中,n为字符串A的长度,m为字符串B的长度)中。

对矩阵中的一点d[i][j],保存从A[0:i]变到B[0:j]的编辑距离。其中,这里S[0:i]变到t[0:j]有三种情况,求得这三种情况的最小值作为最小操作数:

(1)设可以在k1个操作内将s[0:i-1]转换为t[0:j],用k1+1次操作将s[0:i]转化为t[0:j],只需要先在“s[0:i]转化为t[0:j]”的操作开端做1次移除操作移除s[i]将s[0:i]转化为s[0:i-1],然后再做k1个操作就可以转换为t[0:j]。对应表格,对应矩阵d[i][j]处即填入k1+1。(左)


(2)设可以在k2个操作内将s[0:i]转换为t[0:j-1],用k2+1次操作将s[0:i]转化为t[0:j],先用k2次操作将s[0:i]转化为t[0:j-1],然后再执行1次插入操作在“s[0:i]变成t[0:j-1]的操作”的末尾插入“增加t[j]”的一次操作,即可将s[0:i]转化为t[0:j]。对应矩阵d[i][j]处即填入k2+1。(上)


(3)设可以在k3个操作内将s[0:i-1]转化为t[0:j-1] ,此时需分情况讨论:
**若s[i]==t[j],S[0:i]变到t[0:j]就只要k3个操作,对应矩阵d[i][j]处即填入k3;
**若s[i]!=t[j],则需1次换操作加在s[0:i-1]转化为t[0:j-1]的操作数基础上就可以将S[0:i]变到t[0:j],共k3+1次。对应矩阵d[i][j]处即填入k3+1。(左上角)

其实,通过上面三种情况的分析,我们可以得到下面这个递推公式:


实现过程

下面我们用一个简单的例子来实现下算法的过程,以abc和abe这两个字符串为例

  1. 首先进行如下初始化(开辟d[n+1][m+1]数据空间,相应位置数据初始化):

    (ps:”A处”是一个标记,只是为了方便讲解,不是这个表的内容。)

  2. 计算A处的值

    它的值取决于:左边的1、上边的1、左上角的0.
    按照上面我们的分析:
    上面的值和左面的值都要求加1,这样得到1+1=2。
    A处 由于是两个a相同,左上角的值加0.这样得到0+0=0。
    这是后有三个值,左边的计算后为2,上边的计算后为2,左上角的计算为0,所以A处 取他们里面最小的0.

  3. 于是表成为下面的样子

    在B处 会同样得到三个值,左边计算后为3,上边计算后为1,在B处 由于对应的字符为a、b,不相等,所以左上角应该在当前值的基础上加1,这样得到1+1=2,在(3,1,2)中选出最小的为B处的值。

  4. 于是表就更新了

    C处 计算后:上面的值为2,左边的值为4,左上角的:a和e不相同,所以加1,即2+1,左上角的为3。在(2,4,3)中取最小的为C处 的值。

  5. 依次推得到

    I处: 表示abc 和abe 有1个需要编辑的操作。这个是需要计算出来的。
    同时,也获得一些额外的信息。
    A处: 表示a 和a 需要有0个操作。字符串一样
    B处: 表示ab 和a 需要有1个操作。
    C处: 表示abe 和a 需要有2个操作。
    D处: 表示a 和ab 需要有1个操作。
    E处: 表示ab 和ab 需要有0个操作。字符串一样
    F处: 表示abe 和ab 需要有1个操作。
    G处: 表示a 和abc 需要有2个操作。
    H处: 表示ab 和abc 需要有1个操作。
    I处: 表示abe 和abc 需要有1个操作。


程序实现

#include<bits/stdc++.h>
using namespace std; int min(int a,int b,int c)
{
return (a<b)?(a<c?a:c):(b<c?b:c);
}
int main()
{
FILE * file;
freopen("input.txt", "r", stdin);
freopen("output.txt","w",stdout); int d[6][8];
string a,b;
cin>>a>>b; for (int i=0;i<=b.size()+1;i++)
{
for (int j=0; j<=a.size()+1;j++)
{
if (i==0&&j==0)
d[i][j]=0;
else if (i==0&& j > 0)
d[i][j]=j;
else if (i>0&&j==0)
d[i][j]=i; else if(i>=1&&j>=1)
{
int k =((b[i-1]==a[j-1])?0:1);
d[i][j]=min(d[i-1][j]+1, d[i][j-1]+1,d[i-1][j-1]+k);
}
}
}
/*
for(int i=0;i<b.size()+1;i++)
{
for(int j=0;j<a.size()+1;j++)
{
cout<<d[i][j]+" ";
}
cout<<endl;
}
*/
cout<<d[b.size()+1][a.size()+1];
return 0;
}

更多

https://my.oschina.net/mustang/blog/58125
https://blog.csdn.net/the_k1/article/details/78442814
https://www.cnblogs.com/cangT-Tlan/p/6219005.html
http://www.cnblogs.com/jiabei521/p/3353390.html
http://wdhdmx.iteye.com/blog/1343856

【附:一文一图】

动态规划 001 - 编辑距离(Levenshtein Distance)问题的更多相关文章

  1. 字符串相似度算法(编辑距离Levenshtein Distance)的应用场景

    应用场景 DNA分析: 将DNA的一级序列如β-球蛋白基因的第一个外显子(Exon)转化为分子“结构图”,然后由所得“结构图”提取图的不变量,如分子连接性指数.以图的不变量作为自变量,再由相似度计算公 ...

  2. C#实现Levenshtein distance最小编辑距离算法

    Levenshtein distance,中文名为最小编辑距离,其目的是找出两个字符串之间需要改动多少个字符后变成一致.该算法使用了动态规划的算法策略,该问题具备最优子结构,最小编辑距离包含子最小编辑 ...

  3. Levenshtein Distance算法(编辑距离算法)

    编辑距离 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符, ...

  4. 扒一扒编辑距离(Levenshtein Distance)算法

    最近由于工作需要,接触了编辑距离(Levenshtein Distance)算法.赶脚很有意思.最初百度了一些文章,但讲的都不是很好,读起来感觉似懂非懂.最后还是用google找到了一些资料才慢慢理解 ...

  5. 用C#实现字符串相似度算法(编辑距离算法 Levenshtein Distance)

    在搞验证码识别的时候需要比较字符代码的相似度用到"编辑距离算法",关于原理和C#实现做个记录. 据百度百科介绍: 编辑距离,又称Levenshtein距离(也叫做Edit Dist ...

  6. [转]字符串相似度算法(编辑距离算法 Levenshtein Distance)

    转自:http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=981 http://www.cnblogs.com/ivanyb/archi ...

  7. Levenshtein Distance(编辑距离)算法与使用场景

    前提 已经很久没深入研究过算法相关的东西,毕竟日常少用,就算死记硬背也是没有实施场景导致容易淡忘.最近在做一个脱敏数据和明文数据匹配的需求的时候,用到了一个算法叫Levenshtein Distanc ...

  8. 利用Levenshtein Distance (编辑距离)实现文档相似度计算

    1.首先将word文档解压缩为zip /** * 修改后缀名 */ public static String reName(String path){ File file=new File(path) ...

  9. 字符串相似度算法(编辑距离算法 Levenshtein Distance)(转)

    在搞验证码识别的时候需要比较字符代码的相似度用到“编辑距离算法”,关于原理和C#实现做个记录. 据百度百科介绍: 编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个 ...

随机推荐

  1. msql 数据库介绍和启动

    什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但 ...

  2. (转\整)UE4游戏优化 多人大地型游戏的优化(三)GPU的优化

    施主分享随缘,评论随心,@author:白袍小道 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题) 2.因 ...

  3. 【视觉SLAM14讲】ch3课后题答案

    1.验证旋转矩阵是正交矩阵 感觉下面这篇博客写的不错 http://www.cnblogs.com/caster99/p/4703033.html 总结一下:旋转矩阵是一个完美的矩阵——正交矩阵.①行 ...

  4. go语言的学习网站

    1)http://www.runoob.com/go/go-data-types.html 2)https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/ ...

  5. CentOS 6.3 下 vsftp搭建

    环境:CentOS6.3 ftp的三种用户模式 匿名用户:vsftp默认开启匿名用户,但只允许下载不允许上传:匿名用户anonymous或ftp:匿名用户目录/var/ftp,但实际上vsftp对匿名 ...

  6. HDU 4714 Tree2cycle 找规律

    假设最少删除的边的个数为cost,显然,最终答案即为cost+cost+1 (因为删除一条边,就会增加一个链,所以删除cost条边后,就会有cost+1条链,将这cost+1条链连接起来的代价为cos ...

  7. poj 3436 网络流构图经典

    ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6012   Accepted: 2 ...

  8. ubuntu服务器环境配置参考

    一.基本的Linux系统命令: ls 查看当前目录下的文件及文件夹 cd /var/www/html 转换目录到/var/www/html cd abc/ddd/ 转换目录到当前目录下的abc文件夹下 ...

  9. [洛谷P4630][APIO2018] Duathlon 铁人两项

    题目大意:给一张无向图,求三元组$(u,v,w)$满足$u->v->w$为简单路径,求个数 题解:圆方树,缩点后$DP$,因为同一个点双中的点一定地位相同 卡点:1.$father$数组开 ...

  10. hdu 2829 斜率DP

    思路:dp[i][x]=dp[j][x-1]+val[i]-val[j]-sum[j]*sum[i]+sum[j]*sum[j]; 其中val[i]表示1~~i是一段的权值. 然后就是普通斜率dp做法 ...