C.编辑距离
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Description
俄罗斯科学家 Vladimir Levenshtein 在 1965 年提出了编辑距离概念。编辑距离,又称 Levenshtein 距离,是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许 可的三种编辑操作包括插入一个字符、删除一个字符、将一个字符替换成另一个字符。
至今,编辑距离一直在相似句子检索的领域中发挥着不可忽视的作用。 我们不妨来设计一个程序,计算两个字符串的编辑距离。
Input
输入数据的第一行是一个正整数,表示一共有几组数据。 每组数据有两行,每行一个字符串。
* 每个字符串长度不超过 1000
* 字符串中只含小写英文字母
Output
对于每组数据,请输出一个整数表示两个字符串的编辑距离。 每个答案占一行。
Sample Input
2 david vivian abc aabbcc
Sample Output
4
3
先来解释一下编辑距离动态规划算法的理解:
有字符串a和b,设dp[i][j]为字符串a长度为i的子串到字符串b长度为j的子串的编辑距离。
那么显然有如下动态规划状态转移方程:
①dp[0][0]=0;
②dp[i][0]=i;(删掉所有i个字符)
③dp[0][j]=j;(添加所有j个字符)
④dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+f);(对于从i-1到j或i到j-1,都要在增添一步才能到dp[i][j];对于从i-1到j-1的情况,若两个字符串最后一个字符相同则不需要再加一步,否则,需要替换,f=1)
编辑距离代码实现:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
int t;
int dp[1000][1000];
char a[100],b[100];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%s%s",a,b);
int l1,l2;
l1=strlen(a);
l2=strlen(b);
for(int i=0; i<=l1; i++)
dp[i][0]=i;
for(int i=0; i<=l2; i++)
dp[0][i]=i;
for(int i=1; i<=l1; i++)
{
for(int j=1; j<=l2; j++)
{
int f;
if(a[i]==b[j])
f=0;
else
f=1;
dp[i][j]=min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+f);
}
}
printf("%d\n",dp[l1][l2]);
}
return 0;
}