AC自动机【萌新文章】
2024-08-25 18:20:32
我这个蒟蒻第一次写博客,有点小激动呢。
主要是最近刚学了AC自动机,学得糟糟糕糕,记录一下,看到dalao们都在写博客,决定自己也写一波【我好水的啦,写的也不好】
AC自动机大概就是 Trie+KMP=AC自动机
嗯,在KMP中,引入了字符串失配最优转移方案:失配函数f[i],在j位匹配失败后,便转到f[j]位匹配
同样的道理,AC自动机就是升维的KMP,在匹配时不仅要考虑当前模板串,还要顾及其它模板串,所以失配函数还要顾及其它模板串,匹配成功也要考虑其它模板串
所以,AC自动机采用了bfs构造f[],还引入了last[]后缀链接,用以指向当前串匹配成功时同时可以匹配成功的串
具体来讲AC自动机有三个操作
插入:
与trie树的插入方式相同
void insert(int id)
{
int u=0;
for(int i=0;i<len[id];i++)
{
int v=P[i]-'a';
if(!ch[u][v])
{
ch[u][v]=++siz;
fill(ch[siz],ch[siz]+26,0);
}
u=ch[u][v];
}
val[u]=id;
}
构造失配函数:
这里采用了优化方法,将子节点不存在的子节点指针直接指向f[]函数指向节点的子节点,然后在匹配时甚至可以不用f[]函数,因为在构造时已经提前把匹配不成功时的指向指向了f[]指针,这能节省不少时间。
总的过程采用bfs构造f[],同时构造last,通过f[]检查是否可以转移
具体思想与KMP相同
void getfail()
{
queue<int> q;
for(int i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]);
int u,v;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
v=ch[u][i];
if(!ch[u][i])
{
ch[u][i]=ch[f[u]][i];
continue;
}
q.push(v);
f[v]=ch[f[u]][i];
last[v]=val[f[v]] ? f[v]:last[f[v]];
}
}
}
匹配:
void AC()
{
vis[0]=true;
ans=0;
char c=getchar();
int id,u=0;
while(!isalpha(c)) c=getchar();
for(int i=1;isalpha(c);i++)
{
vis[i]=false;
id=c-'a';
u=ch[u][id];
if(val[u]) print(u);
else if(last[u]) print(last[u]);
c=getchar();
}
}
print为沿着last的打印函数
嗯就这样
最新文章
- ABAP SPLIT
- 黑马----JAVA异常
- man命令中的文本操作
- jsp 三大指令和动作标签
- VTK序列图像的读取[转][改]
- sqlserver 时间转换
- 关于Unity导出的Android应用在小米、联想等机型上崩溃的问题
- web服务器小记
- PullToRefreshListView上拉加载、下拉刷新 eclipse项目
- iOS 插件化开发汇总 Small框架
- nyoj_14:会场安排问题
- ArcGIS自定义工具箱-显示地图文档结构
- mybatis 插入数据 在没有commit时 获取主键id
- 8.3 C++格式标识和操纵器
- 终止执行js的方法
- LeetCode题解之Add Strings
- linux升级mysql到5.7
- (转)mysql、innodb和加锁分析
- php cache类代码(php数据缓存类)
- USACO 2012 Feb Cow Coupons
热门文章
- Linux——CentOS7添加/删除用户和用户组(学习笔记)
- jquery 3.0 新版本
- v-if、v-show 指令
- 基于Ubuntu+kodexplorer可道云的私有云网盘
- C++指定位数小数输出
- Ubuntu16.04Server版离线安装Nginx1.8.1+Mysql5.7.23+Python3.6.2
- 2-Fourth Scrum Meeting20151204
- 任务看板-Monday
- Sprint10
- 结对作业(1.0版)(bug1已修复)