日常吐槽:关于DP,有一种莫名的恐惧...maybe源于与mtw大佬与quantum11大佬,初中时抬老师爬楼梯的经历。。。
言归正传:
编辑距离
【题目描述】
设A和B是两个字符串。我们要用最少的字符操作次数,将字符串A转换为字符串B。这里所说的字符操作共有三种:
1、删除一个字符;
2、插入一个字符;
3、将一个字符改为另一个字符。
对任意的两个字符串A和B,计算出将字符串A变换为字符串B所用的最少字符操作次数。
【输入】
第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于2000。
【输出】
只有一个正整数,为最少字符操作次数。
【输入样例】
sfdqxbw
gfdgw
【输出样例】
4
【思路】
比较基础的一道DP题目,(我才不会告诉你们,我也是看了书才会做)~
既然是DP,那么我们分析一下子问题,当前处理A到第i个字符,处理B到第j个字符
状态f[i][j]代表此时最小的编辑距离
不难推出:
F[I][J]=MIN{F[I-1][J-1],F[I-1][J],F[I][J-1]}+1;
好简单
的样子
额...
不存在的
如果A[I]==B[I]的话,我们发现
根本不用修改
then:
if(a[i]==b[j])
f[i][j]=min(min(f[i-1][j]+1,f[i][j-1]+1),f[i-1][j-1]);
else
f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
大概就是这个样子的
吧...
接下来
关于边界处理
假设A空:则 for(int j=0;j<=m;j++) f[0][j]=j;
假设B空:则 for(int i=0;i<=n;i++) f[i][0]=i;
就这样...完...完成了?
不存在的
才怪呢...
附上代码
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
char chr=getchar();
int f=1,ans=0;
while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
while(isdigit(chr)) {ans=ans*10;ans+=chr-'0';chr=getchar();}
return ans*f;
}
int f[2005][2005];
int n,m;
char a[2005],b[2005];
int main()
{
scanf("%s\n%s",a+1,b+1);
n=strlen(a+1);
m=strlen(b+1);
for(int i=0;i<=n;i++) f[i][0]=i;
for(int j=0;j<=m;j++) f[0][j]=j;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
f[i][j]=min(min(f[i-1][j]+1,f[i][j-1]+1),f[i-1][j-1]);
else
f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
}
cout<<f[n][m];
return 0;
}