编辑距离
2016-08-15 17:28
232 查看
编辑距离
输入
第1行:字符串a(a的长度 <= 1000)。
第2行:字符串b(b的长度 <= 1000)。
输出
输出a和b的编辑距离(将串a与b变为相同的字符串需要的操作步数)
输入示例
kitten
sitting
输出示例
3
这个问题之所以难,是难在有“添加”“删除”这样的操作,很麻烦。我们试试换个角度理解问题,把它看成字符串对齐的问题,事实上从生物信息学对比基因的角度,我们可以这样理解问题。
给定字符串S和T,我们可以用一种特殊字符促成两个字符串的对齐。我们加的特殊字符是“-”, 我们允许在S和T中任意添加这种特殊字符使得它长度相同,然后让这两个串“对齐”,最终两个串相同位置出现了不同字符,就扣1分,我们要使得这两个串对齐扣分尽量少。
对于例子 我们实际上采取了这样的对齐方式:
12345
ABCF-
DB-FG
注意:如果要对齐,两个“-”相对是没有意义的,所以我们要求不出现这种情况。
那么看一下:
(1) S,T对应位置都是普通字符,相同,则不扣分。 例如位置2,4
(2) S,T对应位置都是普通字符,不同,则扣1分。 例如位置1
(3) S在该位置是特殊字符,T在该位置是普通字符,则扣1分,例如位置5
(4) S在该位置是普通字符,T在该位置是特殊字符,则扣1分,例如位置3
我们来看看扣分项目对应什么?
(1) 不扣分,直接对应
(2) 对应把T中对应位置的字符修改
(3) 对应在T中删除该字符
(4) 对应在T中添加该字符
好了,目标明确,感觉像不像 LCS?我们尝试一下:
设f(i,j)表示S的前i位和T的前j位对齐后的最少扣分。
那我们来看看最后一位,对齐的情况
(1) 必须S[i] == T[j], 这时前i – 1和j – 1位都已经对齐了,这部分肯定要最少扣分。这种情况下最少的扣分是f(i-1,j-1)
(2) 和(1)类似,S[i]≠T[j],这种情况下最少的扣分是f(i -1, j – 1) + 1
(3) S的前i位和T的前(j – 1)位已经对齐了,这部分扣分也要最少。这种情况下最少的扣分是f(i,j-1) + 1
(4) S的前(i-1)位已经和T的前j位对齐了,这部分扣分要最少。这种情况下最少的扣分是f(i-1,j) + 1
具体f(i,j)取什么值,显然是要看哪种情况的扣分最少。
为了方便,我们定义函数same(i,j)表示如果S[i] == T[j]则为0,否则为1。
我们来表示一下递推式:
f(i,j) = min(f(i – 1, j – 1) + same(i,j), f(i – 1,j ) + 1, f(i, j – 1) + 1)
初值是什么?
f(0, j) = j
f(i, 0) = i
输入
第1行:字符串a(a的长度 <= 1000)。
第2行:字符串b(b的长度 <= 1000)。
输出
输出a和b的编辑距离(将串a与b变为相同的字符串需要的操作步数)
输入示例
kitten
sitting
输出示例
3
这个问题之所以难,是难在有“添加”“删除”这样的操作,很麻烦。我们试试换个角度理解问题,把它看成字符串对齐的问题,事实上从生物信息学对比基因的角度,我们可以这样理解问题。
给定字符串S和T,我们可以用一种特殊字符促成两个字符串的对齐。我们加的特殊字符是“-”, 我们允许在S和T中任意添加这种特殊字符使得它长度相同,然后让这两个串“对齐”,最终两个串相同位置出现了不同字符,就扣1分,我们要使得这两个串对齐扣分尽量少。
对于例子 我们实际上采取了这样的对齐方式:
12345
ABCF-
DB-FG
注意:如果要对齐,两个“-”相对是没有意义的,所以我们要求不出现这种情况。
那么看一下:
(1) S,T对应位置都是普通字符,相同,则不扣分。 例如位置2,4
(2) S,T对应位置都是普通字符,不同,则扣1分。 例如位置1
(3) S在该位置是特殊字符,T在该位置是普通字符,则扣1分,例如位置5
(4) S在该位置是普通字符,T在该位置是特殊字符,则扣1分,例如位置3
我们来看看扣分项目对应什么?
(1) 不扣分,直接对应
(2) 对应把T中对应位置的字符修改
(3) 对应在T中删除该字符
(4) 对应在T中添加该字符
好了,目标明确,感觉像不像 LCS?我们尝试一下:
设f(i,j)表示S的前i位和T的前j位对齐后的最少扣分。
那我们来看看最后一位,对齐的情况
(1) 必须S[i] == T[j], 这时前i – 1和j – 1位都已经对齐了,这部分肯定要最少扣分。这种情况下最少的扣分是f(i-1,j-1)
(2) 和(1)类似,S[i]≠T[j],这种情况下最少的扣分是f(i -1, j – 1) + 1
(3) S的前i位和T的前(j – 1)位已经对齐了,这部分扣分也要最少。这种情况下最少的扣分是f(i,j-1) + 1
(4) S的前(i-1)位已经和T的前j位对齐了,这部分扣分要最少。这种情况下最少的扣分是f(i-1,j) + 1
具体f(i,j)取什么值,显然是要看哪种情况的扣分最少。
为了方便,我们定义函数same(i,j)表示如果S[i] == T[j]则为0,否则为1。
我们来表示一下递推式:
f(i,j) = min(f(i – 1, j – 1) + same(i,j), f(i – 1,j ) + 1, f(i, j – 1) + 1)
初值是什么?
f(0, j) = j
f(i, 0) = i
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char a[1010]; char b[1010]; int same[1010][1010]; int dp[1010][1010]; int lena,lenb; void init() { for(int i=0;i<=lena;i++) { for(int j=0;j<=lenb;j++) { dp[0][j]=j; dp[i][0]=i; if(a[i]==b[j]) same[i][j]=0; else same[i][j]=1; } } } int main() { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); memset(same,-1,sizeof(same)); scanf("%s%s",a+1,b+1); //这样输入是为了让字符串的下标从1开始; a[0]='0',b[0]='0'; //这里好好体会,a【0】,b【0】不参与编辑距离的计算,只是为了防止出现:输入的字符串长度为零(空串); lena=strlen(a+1); lenb=strlen(b+1); //printf("%c %c",a[1],b[1]); init(); for(int i=1;i<=lena;i++) { for(int j=1;j<=lenb;j++) { dp[i][j]=min(dp[i-1][j-1]+same[i][j],min(dp[i][j-1]+1,dp[i-1][j]+1));//状态转移方程 } } printf("%d\n",dp[lena][lenb]); return 0; }
相关文章推荐
- 编辑距离问题
- Google算法题:M-编辑距离
- 【原】 POJ 1035 Spell checker 编辑距离 解题报告
- 程序员编程艺术第二十八~二十九章:最大连续乘积子串、字符串编辑距离
- 51Nod 1183 编辑距离 (DP
- edit distance 编辑距离
- dp-编辑距离HLG
- 插入、删除、修改操作 代价不等的 最短编辑距离 动态规化求法
- 最短编辑距离 poj3356
- 动态规划之编辑距离
- 高效比对,返回最短编辑距离算法匹配度最高的数据
- 51nod1183 编辑距离
- 51Nod 1183 编辑距离 dp
- 有一亿个数,输入一个数,找出与它编辑距离在3以内的数,比如输入6(0110),找出0010等数,数是32位的。
- POJ 3356 AGTC(最小编辑距离)
- hrbust 哈理工 1289 编辑距离
- Codeforces 67C Sequence of Balls 编辑距离 dp
- 动态规划 - 编辑距离
- 华为OJ 计算字符串相似度或者编辑距离 JAVA
- LeetCode刷题 | 72. Edit Distance 难题 编辑距离dp