1206: 字符串的修改找规律法和经典Edit Distance法

1206: 字符串的修改


时间限制: 1 Sec  内存限制: 128 MB
提交: 816  解决: 424

题目描述
设A和B是两个字符串。我们要用最少的字符操作次数,
将字符串A转换为字符串B。这里所说的字符操作共有三种:
1. 删除一个字符;
2. 插入一个字符;
3. 将一个字符改为另一个字符。
对任给的两个字符串A和B,
计算出将字符串A变换为字符串B所用的最少字符操作次数。

输入
第一行为字符串A;第二行为字符串B;
字符串A和B的长度均小于200。
输出
只有一个正整数,为最少字符操作次数。

样例输入 
sfdxbqw
gfdgw
样例输出
4

代码

/*
题目介绍的很清楚,字符串A变为字符串B需要的最少次操作步骤,
并且一共三个操作:     删除、插入、更改。
首先需找出俩个字符串的长度len1和len2,
然后找出来个字符中相同字符的个数,记为 sameAlpha,
如果len1大于len2,
那么len1-len2的部分只能执行删除或更改
(删除和插入操作次数是一样的,但是更改则是包含 删除 和 插入, 
因此尽量用 更改 (则删除 和 插入的这两次操作就变成了 一次 更改操作)
那么需要更改的次数就为len2-sameAlpha,
删除或插入的次数就为len1-len2,
所以总的操作次数为len1-sameAlpha;

本题的重点是 |len1-len2| (取绝对值)的部分执行删除或插入,
则剩下的部分中不相同的字符执行更改,
如果删除后插入就多了一个操作步骤,达不到最少的操作次数。
*/

#include <string>
#include <iostream>
using namespace std;

int main() {
    string str1, str2;
    getline(cin, str1);
    getline (cin, str2);
    int len1, len2, sameAlpha = 0; // 字符中相同字符的个数,记为 sameAlpha
    len1 = str1.length();
    len2 = str2.length();
    for (int i = 0; i < len1; i++) {
        for (int j = 0; j < len2; j++) {
            if (str1[i] == str2[j]) 
                sameAlpha++;
        }
    }
    printf("%d\n", max(len1 - sameAlpha, len2 - sameAlpha));
    
    return 0;
}

经典方法

dp求解 Minimum Edit Distance

小白分析

很明显的动态规划算法, 刚开始不知道怎么写,后来上网查了查,是一类题, 叫做Edit Distance。
很经典的一类题型,借鉴了两个大牛的博客,写的非常详细

本篇内容将讲述Edit Distance(编辑距离的定义详见正文),
具体又包含3个方面的内容:

代码实现

#include <iostream>
//#include<cstdio>
#include <cstdlib>
//#include<algorithm>
//#include<vector>
#include <cstring>
//#include<string>
//#include<map>
using namespace std;
#define N 220
int main()
{
    int lenA, lenB, i, j;
    int dpArr[N][N];
    char a[N], b[N];
    while (~scanf("%s%s", a, b))
    {
        lenA = strlen(a);
        lenB = strlen(b);
        memset(dpArr, 0, sizeof(dpArr));
        for (i = 0; i <= lenA; i++)
            dpArr[i][0] = i;
        for (j = 0; j <= lenB; j++)
            dpArr[0][j] = j;

        
// 编辑距离 
/*
请读者深入理解一下上图中的循环体部分: D(i,j)可能的取值为:
1. D(i-1, j) +1 ;
2. D(i, j-1) +1 ;
3. D(i-1, j-1) + 1 (当X新增加的字符和Y新增加的字符不同时,需要替换)
或者 + 0(即两个字符串新增加的字符相同)
下述代码即对字符串 一步步求ED形成的表。
*/
        // 打表
        for (j = 1; j <= lenB; j++)
            for (i = 1; i <= lenA; i++)
            {
                if (a[i - 1] == b[j - 1])
                    dpArr[i][j] = dpArr[i - 1][j - 1];
                else
                    dpArr[i][j] = min(min(dpArr[i - 1][j] + 1, dpArr[i][j - 1] + 1), dpArr[i - 1][j - 1] + 1);
            }
        printf("%d\n", dpArr[lenA][lenB]);
    }
    return 0;
}


知识拓展

1. Definition of Minimum Edit Distance

在这里插入图片描述

2. Computing Minimum Edit Distance

在这里插入图片描述

3. 算法关键

上图中使用的是”Levenshtein Distance“即替换的成本为2.
请读者深入理解一下上图中的循环体部分: D(i,j)可能的取值为:
1. D(i-1, j) +12. D(i, j-1) +13. D(i-1, j-1) + 2 (当X新增加的字符和Y新增加的字符不同时,需要替换)或者 + 0(即两个字符串新增加的字符相同)
上图即对字符串 INTENTION 和 EXECUTION 一步步求ED形成的表。

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值