第1行:字符串a(a的长度 <= 1000)。 第2行:字符串b(b的长度 <= 1000)。
输出a和b的编辑距离
kitten sitting
3
在网上也看到了专门讲解编辑距离算法的帖子,其实就是dp。
首先是dp[i][j]数组的初始化,两个字符串a和b。如图:
dp[i][j]表示字符串a[1,2,...i]与字符串b[1,2,...j]的编辑距离(这里字符串从1开始算)。
编辑距离有三种情况得到:
1. 假设我们已经知道了 dp[i-1][j] 即 a[1...i-1], b[1...j]的编辑距离,那么我们只要往a[1...i-1]中再添加一个字符就能得到a[1...i], 所以dp[i][j]=dp[i-1][j]+1;
2. 假设我们已经知道了 dp[i][j-1] 即 a[1...i], b[0...j-1]的编辑距离,那么我们只要往b[1...j-1]中再添加一个字符就能得到b[1...j], 所以dp[i][j]=dp[i][j-1]+1;
3. 假设我们已经知道了 dp[i-1][j-1] 即 a[1...i-1], b[1...j-1]的编辑距离,如果a[i]=b[j], 那么dp[i][j]=dp[i-1][j-1], 如果a[i]!=b[j],那么我们需要改变a[i-1]使其等于b[j-1], 所以dp[i][j]=dp[i-1][j-1]+1;
根据这三种情况可以列出状态转移方程,详细看代码,最后的到的矩阵为
其实根据这个矩阵可以观察出来 若两个字符串在同一位相同时,dp[i][j]的值为它左,上,左上三个数的最小值。若不相同,dp[i][j]为这三个数最小值+1;
#include<stdio.h>
#include<string.h>
#define maxn 1010
char s1[maxn],s2[maxn];
int dp[maxn][maxn];
int min(int a,int b,int c)
{
if(a>b)
a=b;
if(a>c)
return c;
else
return a;
}
int main()
{
int i,j;
while(scanf("%s%s",s1+1,s2+1)!=EOF)
{
int l1=strlen(s1+1);
int l2=strlen(s2+1);
for(i=0;i<l1;i++)
dp[i][0]=i;
for(i=0;i<l2;i++)
dp[0][i]=i;
for(i=1;i<=l1;i++)
{
for(j=1;j<=l2;j++)
{
int t=s1[i]==s2[j]?0:1;
dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+t);//状态转移方程
}
}
printf("%d\n",dp[l1][l2]);
}
}