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. how to make choices about girls?

    yb ldge nvhl, yige hf csmn, hv bmig, hv zofj, hfyb uhjnxn;ldyige ybdm bfbfde, gjjt hf djip, djui hfk ...

  2. 那些年被我坑过的Python——山外有山(第四章)

    装饰器: 定义: 本质是函数,(装饰其他函数)就是为其他函数添加附加功能原则: 1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 优点: 装饰器带来的最直观的好处:减少对函数的细化 ...

  3. Android 5.0 技术新趋势

    由于 Android 的版本分裂比较严重,整个新系统升级可能需要一两年甚至更长时间.所以目前使用 Android 5.0 的大部分是喜欢尝鲜的用户,同时现在市场上能够很好支持 Android 5.0 ...

  4. Sequence《优先队列》

    Description Given m sequences, each contains n non-negative integer. Now we may select one number fr ...

  5. Extjs4中用combox做下拉带图片的下拉框

    今天,莫名的来个一个需求,需要做的一个下拉框中,需要有图片,这不...谷歌+度娘然后找网友,终于搞定.现在感谢这些提供资料的友友... 效果如图:

  6. Apache HTTP Server mod_session_dbd 远程安全漏洞(CVE-2013-2249)

    漏洞版本: Apache 2.4.2 漏洞描述: BUGTRAQ ID: 61379 CVE(CAN) ID: CVE-2013-2249 Apache HTTP Server是开源HTTP服务器. ...

  7. 【动态规划】Codeforces 711C Coloring Trees

    题目链接: http://codeforces.com/problemset/problem/711/C 题目大意: 给N棵树,M种颜色,已经有颜色的不能涂色,没颜色为0,可以涂色,每棵树I涂成颜色J ...

  8. GitHub上传不了的解决 ssh: connect to host github.com port 22: Bad file number git did not exit cleanly (exit code 128)

    问题情况 本来一直用的是github的客户端,结果现在上传的时候出问题了,去网站上看,新项目已经创建,但是代码却怎么都上传不上去.于是只好用命令行的方式解决. Tortoisegit上是这样说的: g ...

  9. PHP 生命周期,Opcode 缓存。

    1.php 执行的生命周期. 用户发出请求---->.php--->词典扫描--->解析--->创建Opcode--->处理opcode--->响应 这就是php的 ...

  10. 病毒侵袭 - HDU 2896(AC自动机)

    分析:有点需要注意的,输入的字符是所有可见的ASCII码,刚开始没看清一直以为是小写字母.............注意到这点后这题就是裸的自动机了.   代码如下: ================= ...