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. MySQL中删除重复数据只保留一条

    用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 SELECT ...

  2. 理解CSS Clip属性及用法

    应用Clip属性实现的一个简单效果图: 样式写法: .my-element { position: absolute; clip: rect(10px  350px  170px  0); /* IE ...

  3. python连接mysql之pymysql模块

    以下demo均以python2中的mysqldb模块 一.插入数据 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import MySQLdb    conn = MyS ...

  4. 酷炫地给py代码标上行数

    Python IDLE是没有显示行号的功能的,今天学了一个方式可以酷炫地给自己的代码加上行号,该方法直接修改代码,慎用哦!代码如下: import fileinput for line in file ...

  5. PHP调试工具Xdebug安装配置教程

    说道PHP代码调试,对于有经验的PHPer,通过echo.print_r.var_dump函数,或PHP开发工具zend studio.editplus可解决大部分问题,但是对于PHP入门学习的童鞋来 ...

  6. BZOJ 1008 越狱

    Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 In ...

  7. 解决maven仓库有jar包但是maven程序无法下载仓库jar包

    话说,这个问题困扰了我两个多月了已经~~~ 后来发现不知道被谁动了,把我的仓库没有放到仓库组里面~~~ 用admin登录进去,默认密码是admin123,然后看截图操作吧. (记得删除你本地报错说** ...

  8. Spring MVC 教程,快速入门,深入分析(转载)

    作者:赵磊 博客:http://elf8848.iteye.com 下载: Spring的官方下载网址是:http://www.springsource.org/download    (本文使用是的 ...

  9. 【Web Service】WSDL文档

    WSDL文档仅仅是一个简单的XML文档. 它包含一系列描述某个web service的定义. WSDL WSDL 是基于 XML 的语言,用于描述 Web services 以及如何访问它们. WSD ...

  10. 我的VSTO之路(五):Outlook初步开发之联系人扩展

    原文:我的VSTO之路(五):Outlook初步开发之联系人扩展 上一讲我们完成对Word的介绍,文本开始,我将着重介绍Outlook.Outlook是微软Office中一个非常实用的工具,尤其在一个 ...