题目链接:点击打开链接
题意:编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。给出两个字符串a,b,求a和b的编辑距离。
题解:面对这道题的第一思路是用最长公共子序列去写。用两个字符串中较长的减去最长公共子序列,然后发下WA了。后来仔细想了一下推出了一组反例
abcde
bcdef
上面那种错误解法为 5 - 4 = 1
但是实际上应该是2(去掉a然后加个f).
那么换一种想法。这道题要求把a变成b的最少操作数。
然么我们不妨定义DP【i】【j】 表示a串前 i 个字符转化成b串前 j 个字符最小需要到少次。
那么DP【alen】【blen】就是我们要求的结果。
思考DP方程如何去写。
我们有三种操作,
增:这是当a串长度小于b串时。
改:这是a【i】!= b【j】;
删:删去a【i】 或 b【j】;
当 a【i】 != b【j】时
很明显DP【i】【j】 = DP【i-1】【j-1】 + 1;
相等时
DP【i】【j】 = DP【i-1】【j-1】+ 0;
再思考,DP【i】【j】还可以从哪里转移过来,
就是从删这一步
有两种DP【i】【j】 = min(DP【i-1】【j】 + 1 , DP【i】【j-1】+ 1)
然后比较上述两个式子。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 1e3+5;
char a[maxn], b[maxn];
int dp[maxn][maxn];
int main(){
scanf("%s%s", a+1, b+1);
int alen = strlen(a+1);
int blen = strlen(b+1);
for(int i = 0; i <= alen; ++i)
dp[i][0] = i;
for(int j = 0; j <= blen; ++j)
dp[0][j] = j;
for(int i = 1; i <= alen; ++i){
for(int j = 1; j <= blen; ++j){
if(a[i]!=b[j])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = dp[i-1][j-1];
dp[i][j] = min(dp[i][j] , min(dp[i-1][j]+1,dp[i][j-1]+1));
}
}
// for(int i = 0 ; i <= alen ; i ++){
// for(int j = 0; j <= blen ;j ++){
// cout << dp[i][j] << " ";
// }
// cout << endl;
// }
printf("%d\n", dp[alen][blen]);
return 0;
}