一开始讲AC自动机就是在字典树上做一个KMP,吓得我感觉好难,不过了解了以后,感觉也就是有点难度,不吓人。

它只是在字典树上用了KMP的思想

典型问题:给n个模式串和一个文本串,问有多少个模式串在文本串中出现过。

暴力字典树的思路:将n个模式串建立一个字典树,结束时累加一次,文本串开始遍历字典树,标记路径,然后每次结束时候都会回溯到根节点。

用上KMP的思想:有一个预处理,在每一个节点i 加上fail指针,指向一个节点 j(该节点满足的要求:root到j节点的串就是root到i节串的一个后缀)这样如果j节点处刚好属于模式串,就直接加就好(然后标记).

关于怎样广搜处理得到fail,链接:https://www.cnblogs.com/hyfhaha/p/10802604.html

#include<bits/stdc++.h>
#define maxn 1000001
using namespace std;
struct kkk{
int son[26],flag,fail;/*记录单词个数 失配后跳转*/
}trie[maxn];
int n,cnt;
char s[1000001];
queue<int >q;
void insert(char* s){
int u=1,len=strlen(s);
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!trie[u].son[v])trie[u].son[v]=++cnt;
u=trie[u].son[v];
}
trie[u].flag++;
}
void getFail(){
for(int i=0;i<26;i++)trie[0].son[i]=1; //初始化0的所有儿子都是1
q.push(1);trie[1].fail=0; //将根压入队列
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){ //遍历所有儿子
int v=trie[u].son[i]; //处理u的i儿子的fail,这样就可以不用记父亲了
int Fail=trie[u].fail; //就是fafail,trie[Fail].son[i]就是和v值相同的点
if(!v){trie[u].son[i]=trie[Fail].son[i];continue;} //不存在该节点,第二种情况
trie[v].fail=trie[Fail].son[i]; //第三种情况,直接指就可以了
q.push(v); //存在实节点才压入队列
}
}
}
int query(char* s){
int u=1,ans=0,len=strlen(s);
for(int i=0;i<len;i++){
int v=s[i]-'a';
int k=trie[u].son[v]; //跳Fail
while(k>1&&trie[k].flag!=-1){ //经过就不统计了
ans+=trie[k].flag,trie[k].flag=-1; //累加上这个位置的模式串个数,标记已经过
k=trie[k].fail; //继续跳Fail
}
u=trie[u].son[v]; //到下一个儿子
}
return ans;
}
int main(){
cnt=1; //代码实现细节,编号从1开始
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
insert(s);
}
getFail();
scanf("%s",s);
printf("%d\n",query(s));
return 0;
}

AC自动机(初步学习)的更多相关文章

  1. hdu2222 Keywords Search(AC自动机初步)

    题目大意: 给出多个模式串和一个主串,求多少个模式串在主串中出现过. 传送门 这是一道AC自动机的模板题. 在学习AC自动机之前,首先要学习WA自动机.TLE自动机和MLE自动机(雾 AC自动机是一种 ...

  2. 「AC自动机」学习笔记

    AC自动机(Aho-Corasick Automaton),虽然不能够帮你自动AC,但是真的还是非常神奇的一个数据结构.AC自动机用来处理多模式串匹配问题,可以看做是KMP(单模式串匹配问题)的升级版 ...

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

    Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...

  4. AC自动机算法学习

    KMP+TRIE int val[1000100][31],tot; int tr[1000100]; int fail[1000100]; struct AC_Trie{ void clean(){ ...

  5. BZOJ1030 [JSOI2007]文本生成器(AC自动机)

    做到了AC自动机的题目,复习了一下AC自动机,学习了黄学长代码,这个题呢,我们可以模拟在AC自动机上的操作,dp数组f[i][j]表示前i个字符,我们在AC自动机上处在j号节点的方案数. 我们可以计算 ...

  6. KMP,HASH,Trie,AC自动机

    我做个总结算了下午看了一下AC自动机和学习我的大生物(当然是多谢鑫神了)..完了要崩.. 1 KMP 只要是学过的人都觉得比较简单吧 但是学不会的人就感觉很难了,我是那种顿悟的然后感觉非常简单的人过程 ...

  7. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  8. AC自动机学习

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

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

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

随机推荐

  1. ndarray数组的索引和切片

    索引:获取数组中特定位置元素的过程 切片:获取数组元素子集的过程 import numpy as np 一维数组 一维数组的索引和切片与python中的列表类似 索引:若元素个数为n,则索引下标可表示 ...

  2. rsync 增量同步总是多两行数据

    从google云机器rsync日志到本地,并通过logstash格式化后存入elasticsearch,但在实施过程中发现,每次rsync后通过查看elasticsearch,都会将上次已同步的数据再 ...

  3. cocoapods iOS类库管理工具的安装与使用

    CocoaPods是一个管理Swift和Objective-C的Cocoa项目的依赖工具.他可以优雅地帮助你扩展你的项目.简单的说,就是替你管理Swift和Objective-C的Cocoa项目的第三 ...

  4. 时间序列数据库(TSDB)初识与选择(InfluxDB、OpenTSDB、Druid、Elasticsearch对比)

    背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工智能.物联网.机器学习.商业智能.智能预警啊等等. 以前的系统,做数据可视化,信息管理,流程控制.现在业务已经不仅仅满足于这 ...

  5. 字符串匹配算法 之BF、KMP

    示例: 1. 已知字符串str1="acabaabaabcacaabc",求str2="abaabcac"是否在字符串str1中? 2. DNA病毒检测.已知患 ...

  6. Java enum枚举在实际项目中的常用方法

    在项目实际开发过程中,经常会遇到对某些固定的值.字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目 ...

  7. OpenCV中Mat的基本用法:创建、复制

    OpenCV中Mat的基本用法:创建.复制 一.Mat类的创建: 1.方法一: 通过读入一张图像,直接将其转换成Mat对象. Mat image = imread("test.jpg&quo ...

  8. 03 HDFS的客户端操作

    服务器和客户端的概念 hdfs的客户端有多种形式 1.网页形式 2.命令行形式 3.客户端在哪里运行,没有约束,只要运行客户端的机器能够跟hdfs集群联网 参数配置 文件的切块大小和存储的副本数量,都 ...

  9. JavaMail(一):利用JavaMail发送简单邮件

    JavaMail,提供给开发者处理电子邮件相关的编程接口.它是Sun发布的用来处理email的API.它可以方便地执行一些常用的邮件传输.但它并没有包含在JDK中,要使用JavaMail首先要下载ja ...

  10. git 查看commit的提交记录

    相关命令: git log  查看所有提交记录 git show 查看提交详情 示例: git log: git show: 查看指定commit的详情:git show commitId 查看某次c ...