我这个蒟蒻第一次写博客,有点小激动呢。

主要是最近刚学了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的打印函数

嗯就这样

最新文章

  1. ABAP SPLIT
  2. 黑马----JAVA异常
  3. man命令中的文本操作
  4. jsp 三大指令和动作标签
  5. VTK序列图像的读取[转][改]
  6. sqlserver 时间转换
  7. 关于Unity导出的Android应用在小米、联想等机型上崩溃的问题
  8. web服务器小记
  9. PullToRefreshListView上拉加载、下拉刷新 eclipse项目
  10. iOS 插件化开发汇总 Small框架
  11. nyoj_14:会场安排问题
  12. ArcGIS自定义工具箱-显示地图文档结构
  13. mybatis 插入数据 在没有commit时 获取主键id
  14. 8.3 C++格式标识和操纵器
  15. 终止执行js的方法
  16. LeetCode题解之Add Strings
  17. linux升级mysql到5.7
  18. (转)mysql、innodb和加锁分析
  19. php cache类代码(php数据缓存类)
  20. USACO 2012 Feb Cow Coupons

热门文章

  1. Linux——CentOS7添加/删除用户和用户组(学习笔记)
  2. jquery 3.0 新版本
  3. v-if、v-show 指令
  4. 基于Ubuntu+kodexplorer可道云的私有云网盘
  5. C++指定位数小数输出
  6. Ubuntu16.04Server版离线安装Nginx1.8.1+Mysql5.7.23+Python3.6.2
  7. 2-Fourth Scrum Meeting20151204
  8. 任务看板-Monday
  9. Sprint10
  10. 结对作业(1.0版)(bug1已修复)