Minimum Edit Distance POJ 3356 && 51Nod 1183

本文详细介绍了编辑距离的概念及其计算方法,通过实例演示了如何利用动态规划求解两个字符串之间的编辑距离,适用于初学者理解和掌握。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1183 编辑距离

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注
编辑距离,又称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[i][j]所代表的意义很简单:s1 的0~i-1的字符串和s2的0~j-1的Minimum Edit Distance。
三种Edit也很简单,但是思考下面的问题:
为什么要考虑边界问题?
为什么可以这样算就能得出结果?

答一:边界问题是在计算过程中往前推的一个状态,必须做预处理,并且意义也很明显。
答二:这样计算可以得出结果的原因是它考虑了每一种情况,而每一种情况都在之前已经算出。(两个for循环)
#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 105;

int n,sum;
int a[maxn],W;
int dp[maxn*100];

int main()
{
    //freopen("in.txt","r",stdin);

    scanf("%d",&n);
    for(int i = 1;i <= n; i++) {
        scanf("%d",&a[i]);
        sum += a[i];
    }
    W = sum/2;

    for(int i = 1;i <= n; i++) {
        for(int j = W;j >= a[i]; j--) {
            dp[j] = max(dp[j],dp[j-a[i]] + a[i]);
        }
    }
    printf("%d\n",sum - dp[W]*2);

    return 0;
}

POJ3356 A->B和原问题一样,不必过多处理。
不过需要注意POJ是多个样例。


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 1005;

int len1,len2;
char s1[maxn],s2[maxn];
int dp[maxn][maxn];

int min(int x,int y,int z)
{
    int M = x;
    if(M > y)
        M = y;
    if(M > z)
        M = z;
    return M;
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%s%d%s",&len1,s1,&len2,s2) != EOF) {
        memset(dp,0,sizeof(dp));
        for(int i = 0;i <= len1; i++) {
            dp[i][0] = i;
        }
        for(int i = 0;i <= len2; i++) {
            dp[0][i] = i;
        }
        for(int i = 1;i <= len1; i++) {
            for(int j = 1;j <= len2; j++) {
                if(s1[i-1] == s2[j-1])
                    dp[i][j] = dp[i-1][j-1];
                else {
                    dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1;
                }
            }
        }
        printf("%d\n",dp[len1][len2]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值