动态规划之编辑距离:用最少的字符操作将A变换成B
2014-04-18 21:40
465 查看
一、问题描述
设A和B是两个字符串,长度分别为n,m要用最少的字符操作(包括字符的插入、删除、修改),这样的操作称为字符串A到B的操作距离,记为d(A,B)。
二、思路分析
把求解编辑距离分为字符串A从0个字符逐渐增加到全部字符分别要变成字符串B该如何变化的问题。具体来说就是,首先选用str1来存储字符串A,str2来存储字符串B,distance矩阵来进行具体的运算。考虑到最简单的情况,str1的长度为0,str2长度不为0;str1长度不为0,str2长度为0,对前一种情况的编辑距离就是m,后一种则是n。为什么?因为str1为0的时候要么对str1进行添加,即添加m位的str2,要么对str2进行m个删除操作;str2为0的时候,要么对str1进行n个删除操作,要么对str2进行n个添加操作。接下来我们着重考虑一般情况,distance矩阵为
[m],假定我们从distance[0][0]开始一直操作到了distance[i][j]位置,其中删除操作肯定是str1比str2长,插入操作str1比str2短,我们所要做的是对distance[i-1][j]
、distance[i][j-1]、distance[i-1][j-1]存的数进行比较,其中最小的就是当前str1和str2的编辑距离。
三、实现过程
这里,我们把矩阵抽象出来,
distance矩阵
在A处,由于两个a相同,左上角为0,为左上角的0+0;B处,左边加1后得到3,上边加1后为1,二者不相等,这时要为左上角加1,得到2,取三者中的最小值,为1,以下内容类推,最终结果为I的值。
四、代码实现
设A和B是两个字符串,长度分别为n,m要用最少的字符操作(包括字符的插入、删除、修改),这样的操作称为字符串A到B的操作距离,记为d(A,B)。
二、思路分析
把求解编辑距离分为字符串A从0个字符逐渐增加到全部字符分别要变成字符串B该如何变化的问题。具体来说就是,首先选用str1来存储字符串A,str2来存储字符串B,distance矩阵来进行具体的运算。考虑到最简单的情况,str1的长度为0,str2长度不为0;str1长度不为0,str2长度为0,对前一种情况的编辑距离就是m,后一种则是n。为什么?因为str1为0的时候要么对str1进行添加,即添加m位的str2,要么对str2进行m个删除操作;str2为0的时候,要么对str1进行n个删除操作,要么对str2进行n个添加操作。接下来我们着重考虑一般情况,distance矩阵为
[m],假定我们从distance[0][0]开始一直操作到了distance[i][j]位置,其中删除操作肯定是str1比str2长,插入操作str1比str2短,我们所要做的是对distance[i-1][j]
、distance[i][j-1]、distance[i-1][j-1]存的数进行比较,其中最小的就是当前str1和str2的编辑距离。
三、实现过程
这里,我们把矩阵抽象出来,
abc | a | b | c | |
abe | 0 | 1 | 2 | 3 |
a | 1 | A处0 | D1 | G 2 |
b | 2 | B处1 | E0 | H 1 |
e | 3 | C处2 | F1 | I 1 |
四、代码实现
#include<iostream> using namespace std; #define MAX 100 //求三者中的最小值 int minval(int a,int b,int c){ int zhi=min(a,b); int minvalue=min(zhi,c); return minvalue; }
//求二者中的最小值 int min(int a,int b){ return(a>b?b:a); } //编辑距离函数,str1 str2为操作的字符串 void editDistance(char *str1,char *str2){ int lenthofstr1=strlen(str1); int lenthofstr2=strlen(str2); int distance[MAX][MAX]; //变量用来遍历、初始化字符串 int i,j; for(i=0;i<lenthofstr1;i++){ distance[i][0]=i; } for(i=0;i<lenthofstr2;i++){ distance[0][i]=i; } for(i=1;i<lenthofstr1;i++){ for(j=1;j<lenthofstr2;j++){ //如果对应的字符相等,原问题交给子问题处理,即不用任何操作 if(str1[i]==str2[j]){ distance[i][j]=distance[i-1][j-1]; } else{ //否则的话,对左、右、左上角的值进行求最小值 distance[i][j]=minval(distance[i-1][j]+1,distance[i][j-1]+1,distance[i-1][j-1]+1); } cout<<distance[i][j]<<" "; } cout<<endl; } cout<<"最少的操作次数是:"<<distance[lenthofstr1-1][lenthofstr2-1]; } int main(){ char str1[]={"abc"}; char str2[]={"dabc"}; editDistance(str1,str2); return 0; } 五、结果显示
相关文章推荐
- jQuery ajax Load关闭缓存的方法
- hdu4604 不错的子序列问题
- 浏览器兼容性问题
- Leetcode OJ : Reverse Words in a String
- WIN8 的WIFI开启问题
- 在eclipse中创建web项目(非myeclipse)
- 使用register_chrdev注册字符设备
- 使用cdev_add注册字符设备
- java当中内部类分析
- 安装Linux系统
- apache 动态配置虚拟主机的方法
- linux 中ctrl -z ,ctrl - d
- 计算几何模板——不断更新
- APS.NET CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET...”--“拒绝访问。
- Tomcat 配置 JNDI数据源出现Name jdbc is not bound in this Context
- bzoj 3522 tree-dp 暴力
- NYOJ--树的判定
- 想要成为Linux内核高手的四种有效途径
- JavaFX环境的搭建和一个简单的例子
- dns-prefetch