AC自动机

----多个模板的字符串匹配

字典树Trie加上失配边构成

插入操作:ac.insert(p[i],i);
构造失配函数:ac.getFail();
计算文本串T中每个模板串的匹配数:ac.find(T);

时间复杂度 O(n+km) (总长度)

以下是加过注释的LRJ模板:

struct ACauto
{
int ch[MAXN][];// 字典树,类似于前向星,ch[i][j]为当前编号为i的结点,下一个字符为j的所指向的编号。
int size;
int f[MAXN],last[MAXN],val[MAXN],cnt[MAXN];
//val用来在字典树中的模板串末尾处标记,标记为模板串的序号(从1开始)
//last后缀链接:结点J沿着失配指针往回走时,遇到的下一个单词尾结点。
//cnt用来统计配对数,每一个模板对应一个值,所以大小为模板数数量。只在print函数中使用 void init()//初始化
{
size=;//字典树中的节点数
memset(ch[],,sizeof(ch[]));//字典树
memset(cnt,,sizeof(cnt)); //用于统计配对数
} int idx(char c)//用于返回编号
{
return c-'a';
} void insert(char *s,int v)//将字符串s插入字典树中,其中v是字符串的编号,从1开始编号
{
int u=,len=strlen(s);
for (int i=;i<len;i++)
{
int c=idx(s[i]);
if (!ch[u][c])
{
memset(ch[size],,sizeof(ch[size]));
val[size]=;
ch[u][c]=size++;
}
u=ch[u][c];
}
val[u]=v;//在字符串末尾做出标记,标记为字符串的编号i
} void print(int j)//用于输出处理,
{
if (j)
{
cnt[val[j]]++;//成功配对数加1
print(last[j]);//继续沿后缀链接走检查是否和某个模板匹配。
}
} int getFail()//BFS构造失配函数
{
queue <int> q;
f[]=;
for (int c=;c<;c++)//把各个模板的第一个字符压入队列中
{
int u=ch[][c];
if (u)
{
f[u]=;
q.push(u);
last[u]=;
}
} while (!q.empty())
{
int r=q.front(); q.pop();
for (int c=;c<;c++)
{
int u=ch[r][c];
if (!u)
{
ch[r][c]=ch[f[r]][c];//如果节点不存在,直接链接到->失配边所指向的节点,这样能够化简计算
continue;
}
q.push(u);
f[u]=ch[f[r]][c];//构造当前节点的失配函数:如果失配,找到失配点的父亲节点r,父亲沿着失配边f[r]走向下一个节点即可。
last[u]=val[f[u]]?f[u]:last[f[u]];//构造后缀链接:如果沿失配指针走的节点是尾节点,就标记为失配指针指向的节点,
//否则标记为其后缀链接的值(类似于递归)。
}
}
} void find(char *T)//AC自动机主函数,在文本串T中寻找模板
{
int n=strlen(T);
int j=;
for (int i=;i<n;i++)
{
int c=idx(T[i]);//返回字符的编号
while(j&&!ch[j][c]) j=f[j];//如果字符不存在,即失配,就顺着失配边走,直到可以匹配
j=ch[j][c];//如果可以匹配,就走向下一个结点
if (val[j]) print(j);//如果j指向某个模板的尾部则输出
else if (last[j]) print(last[j]);//即使不是某个模板的尾部也要沿后缀链接走,检查是否为某个模板的尾部(如果存在的话)。
}
}
}ac;

AC自动机学习笔记的更多相关文章

  1. AC自动机学习笔记-2(Trie图&&last优化)

    我是连月更都做不到的蒟蒻博主QwQ 考虑到我太菜了,考完noip就要退役了,所以我决定还是把博客的倒数第二篇博客给写了,也算是填了一个坑吧.(最后一篇?当然是悲怆のnoip退役记啦QAQ) 所以我们今 ...

  2. AC自动机板子题/AC自动机学习笔记!

    想知道484每个萌新oier在最初知道AC自动机的时候都会理解为自动AC稽什么的,,,反正我记得我当初刚知道这个东西的时候,我以为是什么神仙东西,,,(好趴虽然确实是个对菜菜灵巧比较难理解的神仙知识点 ...

  3. [AC自动机][学习笔记]

    用途 AC自动机适用于一类用多个子串在模板串中匹配的字符串问题. 也就是说先给出一个模板串,然后给出一些子串.要求有多少个子串在这个模板串中出现过. KMP与trie树 其实AC自动机就是KMP与tr ...

  4. AC自动机学习笔记-1(怎么造一台AC自动机?)

    月更博主又来送温暖啦QwQ 今天我们学习的算法是AC自动机.AC自动机是解决字符串多模匹配问题的利器,而且代码也十分好打=w= 在这一篇博客里,我将讲解AC自动机是什么,以及怎么构建一个最朴素的AC自 ...

  5. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  6. 【AC自动机】【字符串】【字典树】AC自动机 学习笔记

    blog:www.wjyyy.top     AC自动机是一种毒瘤的方便的多模式串匹配算法.基于字典树,用到了类似KMP的思维.     AC自动机与KMP不同的是,AC自动机可以同时匹配多个模式串, ...

  7. AC自动机学习

    今天包括这一周开始学习AC自动机了,有点晚,但我感觉努努力还来得及.4月份还得认认真真攻图论,加油! 为2个月后的邀请赛及省赛.东北赛做准备. 推荐AC自动机学习地址:http://www.cppbl ...

  8. 后缀自动机&回文自动机学习笔记

    在学了一天其实是边学边摆之后我终于大概$get$后缀自动机了,,,就很感动,于是时隔多年我终于决定再写篇学习笔记辽$QwQ$ $umm$和$FFT$学习笔记一样,这是一篇单纯的$gql$的知识总结博, ...

  9. AC自动机学习小结

    AC自动机 简要说明 \(AC\) 自动机,全称 \(Aho-Corasick\ automaton\) ,是一种有限状态自动机,应用于多模式串匹配.在 \(OI\) 中通常搭配 \(dp\) 食用. ...

随机推荐

  1. Ubuntu14 或是其他系统当中关于sublimeSFTP超时解决方法

    一直都使用Sublime的SFTP功能,感觉还不错,好用,但是最近不知道怎么了,使用不成了,提示超时了,于是在网上找一下解决方法,没有找到,于是自己想着试试看,于在搞了一会,发现只要把配制文件当中的s ...

  2. 使用Echarts的五个步骤

     _liuz 2015-07-22 09:35:53 参考网址:http://echarts.baidu.com/doc/start.html 一.制作一个图表容器<div id="m ...

  3. Asynchronous

    http://sporto.github.io/blog/2012/12/09/callbacks-listeners-promises/ http://www.cnblogs.com/liuning ...

  4. TinyMCE下载及使用

    1.TinyMCE下载 官方下载网址:http://www.tinymce.com/ 简体中文语言包下载:http://www.tinymce.com/i18n/index.php?ctrl=lang ...

  5. build Intent

    Intent用于activity之间, fragmetn之间, 或者APP间通信, 主要包含数据和Action两部分: 常见的action是字符串形式的activity指定 Intent intent ...

  6. Java 利用SWFUpload多文件上传 session 为空失效,不能验证的问题 swfUpload多文件上传

    Java 利用SWFUpload多文件上传 session 为空失效,不能验证的问题(转) 我们都知道普通的文件上传是通过表单进行文件上传的,还不能达到异步上传的目的.通过使用某些技术手段,比如jqu ...

  7. 14.5.3 Locks Set by Different SQL Statements in InnoDB

    14.5.3 Locks Set by Different SQL Statements in InnoDB 通过不同的SQL语句设置的锁 在InnoDB中 一个锁定读, 一个UPDATE 或者一个D ...

  8. MFC中菜单栏使用

    1.新建项目: 选择MFC应用程序,应用程序类型选择“基于对话框”: 本文中项目名为:MenuTest 2.新建菜单栏资源: 找到资源视图,右键MenuTest.re选择“添加资源”——选择Menu, ...

  9. vijos1053Easy sssp

    P1053Easy sssp 描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图 ...

  10. ♫【jQuery】detach

    Jquery empty() remove() detach() 方法的区别 <!DOCTYPE html> <html> <head> <meta char ...