编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将kitten一字转成sitting:
sitten (k->s)
sittin (e->i)
sitting (->g)
所以kitten和sitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
给出两个字符串a,b,求a和b的编辑距离。
Input
第1行:字符串a(a的长度 <= 1000)。 第2行:字符串b(b的长度 <= 1000)。
Output
输出a和b的编辑距离
Input示例
kitten sitting
Output示例
3
之前不会做就没去动他,今天偶然在书上看到了这题,仔细思考了一下,以及同时稳固了记忆化形式的dp,嘛,果然还是记忆化的好写些了(现在感觉)~~
思路嘛:
其实和LCS有很大的相似之处,但是这里要考虑到当其中一个串已经没有时,那么剩下的编辑距离是剩余那个串的长度。(这个同时也是递归结束的条件)
然后讨论当a[i]==b[j] || a[i]!=b[j] 这两种情况就好了。
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#include<time.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
#define pi acos(-1.0)
#define Ex exp(1.0)
#define inf 99999999
#define maxn 1010
char a[maxn],b[maxn];
int dp[maxn][maxn];
void init(){
memset(dp,-1,sizeof(dp));
}
int EditDistance(int i,int j){
if(dp[i][j]!=-1){
return dp[i][j];
}
int dis=0;
//下面两个同时也是递归结束的条件,要注意!!
if(strlen(a+i)==0){
dis=strlen(b+j);
}
else if(strlen(b+j)==0){
dis=strlen(a+i);
}
else{
if(a[i]==b[j]){
dis=EditDistance(i+1,j+1);
}
else{
int edIns=EditDistance(i,j+1)+1;
int edDel=EditDistance(i+1,j)+1;
int edRep=EditDistance(i+1,j+1)+1;
dis=min(edIns,min(edDel,edRep));
}
}
dp[i][j]=dis;
return dis;
}
int main(){
init();
scanf("%s",a);
scanf("%s",b);
int dis=EditDistance(0,0);
printf("%d\n",dis);
#ifndef ONLINE_JUDGE
system("pause");
#endif
return 0;
}