计算字符串距离

描述
对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
  1. 修改一个字符(如把“a”替换为“b”)
  2. 删除一个字符(如把“traveling”变为“travelng”)

比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离。
给定任意两个字符串,写出一个算法来计算出他们的距离。
输入
第一行有一个整数n。表示测试数据的组数,
接下来共n行,每行两个字符串,用空格隔开。表示要计算距离的两个字符串
字符串长度不超过1000。
输出
针对每一组测试数据输出一个整数,值为两个字符串的距离。
样例输入
3
abcdefg  abcdef
ab ab
mnklj jlknm
样例输出
1
0
4

假设有两个字符串ai,bi;

a1,a2,a3......ai;

b1,b2,b3......bi;

如果ai==bi

那么ai与bi对于编辑距离无贡献,所以dp[i][j]=dp[i-1][j-1]

而如果ai!=bi

那么有3种情况

1.删除ai 那么dp[i][j]=dp[i-1][j]+1

2.删除bi 那么dp[i][j]=dp[i][j-1]+1

3.修改ai或bi的值 那么dp[i][j]=dp[i-1][j-1]+1;

所以状态转移公式可以推出

                if(a[i-1]==b[j-1])
                    dp[i][j]=dp[i-1][j-1];
                else
                    dp[i][j]=min(dp[i][j-1],min(dp[i-1][j-1],dp[i-1][j]))+1;

而对于初始状态,如果a为空字符串,那么a对b的距离为b的长度,反之亦为

所以

        for(int i=1;i<=len2;i++){
            dp[0][i]=i;
        }
        for(int i=1;i<=len1;i++){
            dp[i][0]=i;
        }

初始还dp数组

下面是完整代码

#include <iostream>
#include<string>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxn=1010;
int dp[maxn][maxn];
int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        //freopen("in.txt","r",stdin);
        string a,b;
        cin>>a>>b;
        int len1=a.length();
        int len2=b.length();
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=len2;i++){
            dp[0][i]=i;
        }
        for(int i=1;i<=len1;i++){
            dp[i][0]=i;
        }
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(a[i-1]==b[j-1])
                    dp[i][j]=dp[i-1][j-1];
                else
                    dp[i][j]=min(dp[i][j-1],min(dp[i-1][j-1],dp[i-1][j]))+1;
            }
        }
        cout<<dp[len1][len2]<<endl;
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/80285833