算法题8 动态规划之字符串相似度
2016-01-28 22:11
309 查看
题目
题目来源:《编程之美》
把两个字符串变成相同的基本操作定义如下:
1. 修改一个字符(如把 a 变成 b)
2. 增加一个字符 (如 abed 变成 abedd)
3. 删除一个字符(如 jeddon 变成 jedon)
针对于 jeddon到jedon 只需要删除一个或增加一个 d 就可以把两个字符串变为相同。把这种操作需要的次数定义为两个字符串的距离 L, 则相似度定义为1/(L+1) 即距离加一的倒数。那么jeddon和jedon的相似度为 1/1+1=1/2=0.5 也就是所两个字符串的相似度是 0.5。
给定任意两个字符串,你是否写出一个是否来计算出它们的相识度。
分析
这是一个多阶段决策问题,每个阶段的决策都和前面子问题的最优决策相关,可以用动态规划来做。
对于字符串str1 和str2,长度分别为m,n,设d[i,j]为str1的第[1—i]字符和str2的第[1—j]个字符之间的距离,
如果str1[i]=str2[j],则d[i,j]=d[i-1,j-1];
如果str1[i]和str2[j]替换一个字符,str1[0-i]和str2[0-j]就相同,比如"student"和"studens",则d[i,j]=d[i-1,j-1]+1;
如果str1[i]增加一个字符,str1[0-i]和str2[0-j]就相同,比如"student"和"students",则d[i,j]=d[i,j-1]+1;
如果str1[i]删除一个字符,str1[0-i]和str2[0-j]就相同,比如"students"和"student",则d[i,j]=d[i-1,j]+1;
由此可以得到关系式:
d[i,0]=i
d[0,j]=j;
d[i,j]=min{d[i-1,j-1]+1,d[i,j-1]+1,d[i-1,j]+1}
算法时间复杂度为O(m*n),空间复杂度为O(m*n)
代码
题目来源:《编程之美》
把两个字符串变成相同的基本操作定义如下:
1. 修改一个字符(如把 a 变成 b)
2. 增加一个字符 (如 abed 变成 abedd)
3. 删除一个字符(如 jeddon 变成 jedon)
针对于 jeddon到jedon 只需要删除一个或增加一个 d 就可以把两个字符串变为相同。把这种操作需要的次数定义为两个字符串的距离 L, 则相似度定义为1/(L+1) 即距离加一的倒数。那么jeddon和jedon的相似度为 1/1+1=1/2=0.5 也就是所两个字符串的相似度是 0.5。
给定任意两个字符串,你是否写出一个是否来计算出它们的相识度。
分析
这是一个多阶段决策问题,每个阶段的决策都和前面子问题的最优决策相关,可以用动态规划来做。
对于字符串str1 和str2,长度分别为m,n,设d[i,j]为str1的第[1—i]字符和str2的第[1—j]个字符之间的距离,
如果str1[i]=str2[j],则d[i,j]=d[i-1,j-1];
如果str1[i]和str2[j]替换一个字符,str1[0-i]和str2[0-j]就相同,比如"student"和"studens",则d[i,j]=d[i-1,j-1]+1;
如果str1[i]增加一个字符,str1[0-i]和str2[0-j]就相同,比如"student"和"students",则d[i,j]=d[i,j-1]+1;
如果str1[i]删除一个字符,str1[0-i]和str2[0-j]就相同,比如"students"和"student",则d[i,j]=d[i-1,j]+1;
由此可以得到关系式:
d[i,0]=i
d[0,j]=j;
d[i,j]=min{d[i-1,j-1]+1,d[i,j-1]+1,d[i-1,j]+1}
算法时间复杂度为O(m*n),空间复杂度为O(m*n)
代码
int SimilarityDegreeOfStrs(char* str1,char* str2) { int len1=strlen(str1); int len2=strlen(str2); int **d=new int*[len1+1]; for (int i=0;i<=len1;i++) { d[i]=new int[len2+1](); } for (int i=0;i<=len1;i++) { d[i][0]=i; } for (int j=0;j<=len2;j++) { d[0][j]=j; } for (int i=1;i<=len1;i++) { for (int j=1;j<=len2;j++) { if (str1[i-1]==str2[j-1]) { d[i][j]=d[i-1][j-1]; }else { int repl=d[i-1][j-1]+1; int add=d[i][j-1]+1; int del=d[i-1][j]+1; d[i][j]=MIN(MIN(repl,add),del); } } } int similarity=d[len1][len2]/(d[len1][len2]+1); //free for (int i=0;i<=len1;i++) { delete[] d[i]; } delete[] d; return similarity; }
相关文章推荐
- 数组前缀和 & 计数排序 uva10474 hdu5327
- Xcode -- apple llvm 6.0 error错误如何解决
- R语言 非标准化求值(Non-standard evaluation, NSE)
- 分量视频 Y'UV, YUV, YCbCr,YPbPr
- LInux 压缩和解压缩命令
- 一则质量小故事
- CF#313-E. Gerald and Giant Chess-dp+组合数学
- IOS之c语言笔记 day06
- response实现验证码
- Jquery 获取对象的几种方式介绍
- 抓包
- struts2模块包含
- 关于linux,我们应该学什么?
- 【Unity Shader】HSV和RGB互转的shader实现
- 欢迎使用CSDN-markdown编辑器
- “苹果茶”内网建站
- 【NYOJ】[74]小学生算术
- 在Keil环境下使用JLink实现printf输出重定向至debug窗口
- UILabel的一些基本使用
- USACO shuttle