动态规划-编辑距离
设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。
输入格式:
第一行是字符串A,文件的第二行是字符串B。
提示:字符串长度不超过2000个字符。
输出格式:
输出编辑距离d(A,B)
输入样例:
在这里给出一组输入。例如:
fxpimu
xwrs 
输出样例:
在这里给出相应的输出。例如:
5
一个字符串有三种操作方式:
1.替换:将字符串的任意一个字符改为另一种字符
2.删除:删除字符串中的任意一个字符
3.插入:添加一个字符在字符串的任意位置
给定两个字符串a、b,求最少操作的数量使两个字符串相等(即编辑距离)
设dp[i][j]表示字符串a、b的子串a[1~i]、b[1~j]的编辑距离
当i=0或j=0时,代表至少有一个空串,显然:
dp[i][j]=max(i,j)
当a[i]=b[j]时,a[i]、b[j]直接排除不考虑,相当于a[1~i]、b[1~j]的编辑距离:
dp[i][j]=dp[i-1][j-1]
当a[i]!=b[j]时,有多种情况:
进行替换操作时,改变a[i]或b[j]使其与另一个相等,编辑距离加1,再加上a[1~i-1]、b[1~j-1]的编辑距离即:dp[i][j]=dp[i-1][j-1]+1
进行删除操作时,删除a[i]或b[j],编辑距离加1再加上a[1~i-1]、b[1~j](或a[1~i]、b[1~j-1])的编辑距离即:dp[i][j]=dp[i-1][j]+1(或dp[i][j]=dp[i][j-1]+1)
进行插入操作时,插入a[i+1]使a[i+1]=b[j](b[j+1]同样),编辑距离加1加a[1~i]、b[1~j-1](或a[1~i]、b[1~j-1])的编辑距离即:dp[i][j]=dp[i-1][j]+1(或dp[i][j]=dp[i][j-1]+1)
可以看出删除和插入操作表达式是一样的
由于dp[i][j]和字符串a,b开始下标不同,所以if语句里是i-1、j-1
#include<iostream> using namespace std; int d[2001][2001]; int main() { int n,m,i,j,k; string a,b; while(cin>>a>>b) { n=a.length(); m=b.length(); for(i=0;i<=n;i++) d[i][0]=i; for(j=0;j<=m;j++) d[0][j]=j; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { k=min(d[i-1][j]+1,d[i][j-1]+1); if(a[i-1]!=b[j-1])d[i][j]=min(k,d[i-1][j-1]+1); else d[i][j]=min(k,d[i-1][j-1]); } cout<<d[n][m]<<'\n'; } return 0; }
posted on 2019-10-21 20:24 我的昵称里必须得有mt 阅读(139) 评论(0) 收藏 举报
                    
                
                
            
        
浙公网安备 33010602011771号