1. 最短编辑距离问题
给定两个字符串 𝐴 和 𝐵,现在要将 𝐴 经过若干操作变为 𝐵,可进行的操作有:
- 删除–将字符串 𝐴 中的某个字符删除。
- 插入–在字符串 𝐴 的某个位置插入某个字符。
- 替换–将字符串 𝐴 中的某个字符替换为另一个字符。
现在请你求出,将 𝐴 变为 𝐵 至少需要进行多少次操作。
输入格式
第一行包含整数 𝑛,表示字符串 𝐴 的长度。
第二行包含一个长度为 𝑛 的字符串 𝐴。
第三行包含整数 𝑚,表示字符串 𝐵 的长度。
第四行包含一个长度为 𝑚 的字符串 𝐵。
字符串中均只包含大小写字母。
输出格式
输出一个整数,表示最少操作次数。
数据范围
1≤𝑛,𝑚≤1000
输入样例:
10
AGTCTGACGC
11
AGTAAGTAGGC
输出样例:
4
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m;
char a[N],b[N];
int f[N][N];
int DP(){
for(int i = 0;i <= n;i ++){
f[i][0] = i;
}
for(int i = 0;i <= m;i ++){
f[0][i] = i;
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
f[i][j] = min(f[i - 1][j], f[i][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);
}
}
}
return f[n][m];
}
int main(){
cin>>n;
for(int i = 1;i <= n;i ++){
cin>>a[i];
}
cin>>m;
for(int j = 1;j <= m;j ++){
cin>>b[j];
}
int res = DP();
cout<<res<<endl;
return 0;
}
2. 多询问编辑距离问题
给定 𝑛 个长度不超过 10 的字符串以及 𝑚 次询问,每次询问给出一个字符串和一个操作次数上限。
对于每次询问,请你求出给定的 𝑛 个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。
每个对字符串进行的单个字符的插入、删除或替换算作一次操作。
输入格式
第一行包含两个整数 𝑛 和 𝑚。
接下来 𝑛 行,每行包含一个字符串,表示给定的字符串。
再接下来 𝑚 行,每行包含一个字符串和一个整数,表示一次询问。
字符串中只包含小写字母,且长度均不超过 10。
输出格式
输出共 𝑚 行,每行输出一个整数作为结果,表示一次询问中满足条件的字符串个数。
数据范围
1≤𝑛,𝑚≤1000,
输入样例:
3 2
abc
acd
bcd
ab 1
acbd 2
输出样例:
1
3
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m,limit;
int f[N][N];
char str[N][N];
int DP(char a[], char b[]){
int lena = strlen(a);
int lenb = strlen(b);
for(int i = 0;i <= lena;i ++){
f[i][0] = i;
}
for(int i = 0;i <= lenb;i ++){
f[0][i] = i;
}
for(int i = 1;i <= lena;i ++){
for(int j = 1;j <= lenb;j ++){
f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
if(a[i - 1] == b[j - 1]){
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);
}
}
}
return f[lena][lenb];
}
int main(){
cin>>n>>m;
for(int i = 0;i < n;i ++){
cin>>str[i];
}
while(m --){
char s[N];
cin>>s>>limit;
int res = 0;
for(int i = 0;i < n;i ++){
if(DP(str[i], s) <= limit){
res ++;
}
}
cout<<res<<endl;
}
return 0;
}