编辑距离与滚动数组优化 - 二维动态规划模板
题目:编辑距离 。
思路
显然,定义
那么对于
如果
- 对于修改操作,我们先要保证 字符串
中前 个字符 已经编辑到了 字符串 中前 个字符,接下来才把 修改成 ,所以转移为 。 - 对于插入操作,因为我们是向
后面插入一个 ,所以我们要保证 字符串 中前 个字符 已经编辑到了 字符串 中前 个字符,再同时往这两个字符串后插一个 ,所以转移为 。 - 对于删除操作,由于我们是删除
字符,所以我们要保证 字符串 中前 个字符 已经编辑到了 字符串 中前 个字符,这样才能删掉 ,所以方程为 。
这三种情况取一个 min 即可。
注意初始化,
#include <bits/stdc++.h>
using namespace std;
string a,b;
int f[2005][2005];
int main()
{
cin>>a>>b;
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=a.length();i++)f[i][0]=i;
for(int i=1;i<=b.length();i++)f[0][i]=i;
for(int i=1;i<=a.length();i++)
{
for(int j=1;j<=b.length();j++)
{
if(a[i-1]==b[j-1])f[i][j]=f[i-1][j-1];
else f[i][j]=min(f[i][j],min(f[i-1][j-1]+1,min(f[i-1][j]+1,f[i][j-1]+1)));
}
}
cout<<f[a.length()][b.length()];
return 0;
}
滚动数组优化
观察到,如果我们把 dp 数组看作一个网格,那么某一个格子的状态一定是由它左边、上边、左上角的格子的状态转移过来的。
因此,我们就可以用滚动数组优化。
但这里的滚动数组不能用像背包一样的倒序转移,因为这里的转移会用到同级的状态:格子左侧。因此我们先要更新格子左边,才能更新这个格子。所以得从左到右转移。
但从左到右转移会覆盖掉左上角的内容,因此我们要把左上角的东西单独记录一下,然后在赋初值的时候注意一下
#include <bits/stdc++.h>
using namespace std;
string a,b;
int f[2005];
int main()
{
cin>>a>>b;
f[0]=0;
for(int i=0;i<=b.length();i++)f[i]=i;
for(int i=1;i<=a.length();i++)
{
int zs=f[0];
f[0]=i;
for(int j=1;j<=b.length();j++)
{
int tmp=zs;
zs=f[j];
if(a[i-1]==b[j-1])f[j]=tmp;
else f[j]=min(tmp+1,min(f[j]+1,f[j-1]+1));
}
}
cout<<f[b.length()];
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战