题解:AcWing 902 最短编辑距离
【题目来源】
AcWing:902. 最短编辑距离 - AcWing题库
【题目描述】
给定两个字符串 \(A\) 和 \(B\),现在要将 \(A\) 经过若干操作变为 \(B\),可进行的操作有:
- 删除–将字符串 \(A\) 中的某个字符删除。
- 插入–在字符串 \(A\) 的某个位置插入某个字符。
- 替换–将字符串 \(A\) 中的某个字符替换为另一个字符。
现在请你求出,将 \(A\) 变为 \(B\) 至少需要进行多少次操作。
【输入】
第一行包含整数 \(n\),表示字符串 \(A\) 的长度。
第二行包含一个长度为 \(n\) 的字符串 \(A\)。
第三行包含整数 \(m\),表示字符串 \(B\) 的长度。
第四行包含一个长度为 \(m\) 的字符串 \(B\)。
字符串中均只包含大小写字母。
【输出】
输出一个整数,表示最少操作次数。
【输入样例】
10
AGTCTGACGC
11
AGTAAGTAGGC
【输出样例】
4
【解题思路】
【代码详解】
《AcWing 902 最短编辑距离》 #动态规划# #线性DP#
#include <bits/stdc++.h>
using namespace std;
const int N = 1005; // 定义常量N,表示数组的最大长度
int n, m; // n和m分别表示两个字符串的长度
char a[N], b[N]; // a和b分别存储两个字符串
int f[N][N]; // f[i][j]表示将a的前i个字符转换成b的前j个字符所需的最少操作次数
int main()
{
// 输入字符串a和b的长度以及字符串内容
// 注意:a和b的输入从下标1开始,即a+1和b+1
cin >> n >> a+1;
cin >> m >> b+1;
// 初始化动态规划数组f
// 当a为空字符串时,将a转换成b的前j个字符需要j次插入操作
for (int i = 0; i <= m; i++) f[0][i] = i;
// 当b为空字符串时,将a的前i个字符转换成b需要i次删除操作
for (int i = 0; i <= n; i++) f[i][0] = i;
// 动态规划求解编辑距离
for (int i = 1; i <= n; i++) // 遍历字符串a的每个字符
for (int j = 1; j <= m; j++) // 遍历字符串b的每个字符
{
// 情况1:将a的前i-1个字符转换成b的前j个字符,然后删除a的第i个字符
// 操作次数为f[i-1][j] + 1
// 情况2:将a的前i个字符转换成b的前j-1个字符,然后插入b的第j个字符
// 操作次数为f[i][j-1] + 1
f[i][j] = min(f[i-1][j] + 1, f[i][j-1] + 1);
// 情况3:如果a[i]等于b[j],则不需要额外操作
// 操作次数为f[i-1][j-1]
// 否则,需要将a[i]替换为b[j],操作次数为f[i-1][j-1] + 1
if (a[i] == b[j])
f[i][j] = min(f[i][j], f[i-1][j-1]);
else
f[i][j] = min(f[i][j], f[i-1][j-1] + 1);
}
// 输出将a转换成b所需的最少操作次数
cout << f[n][m] << endl;
return 0;
}
【运行结果】
10
AGTCTGACGC
11
AGTAAGTAGGC
4
浙公网安备 33010602011771号