文章目录
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) +1 ;
2. D(i, j-1) +1 ;
3. D(i-1, j-1) + 2 (当X新增加的字符和Y新增加的字符不同时,需要替换)或者 + 0(即两个字符串新增加的字符相同)
上图即对字符串 INTENTION 和 EXECUTION 一步步求ED形成的表。