AC自动机(初步学习)
一开始讲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自动机(初步学习)的更多相关文章
- hdu2222 Keywords Search(AC自动机初步)
题目大意: 给出多个模式串和一个主串,求多少个模式串在主串中出现过. 传送门 这是一道AC自动机的模板题. 在学习AC自动机之前,首先要学习WA自动机.TLE自动机和MLE自动机(雾 AC自动机是一种 ...
- 「AC自动机」学习笔记
AC自动机(Aho-Corasick Automaton),虽然不能够帮你自动AC,但是真的还是非常神奇的一个数据结构.AC自动机用来处理多模式串匹配问题,可以看做是KMP(单模式串匹配问题)的升级版 ...
- [AC自动机]【学习笔记】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- AC自动机算法学习
KMP+TRIE int val[1000100][31],tot; int tr[1000100]; int fail[1000100]; struct AC_Trie{ void clean(){ ...
- BZOJ1030 [JSOI2007]文本生成器(AC自动机)
做到了AC自动机的题目,复习了一下AC自动机,学习了黄学长代码,这个题呢,我们可以模拟在AC自动机上的操作,dp数组f[i][j]表示前i个字符,我们在AC自动机上处在j号节点的方案数. 我们可以计算 ...
- KMP,HASH,Trie,AC自动机
我做个总结算了下午看了一下AC自动机和学习我的大生物(当然是多谢鑫神了)..完了要崩.. 1 KMP 只要是学过的人都觉得比较简单吧 但是学不会的人就感觉很难了,我是那种顿悟的然后感觉非常简单的人过程 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- AC自动机学习
今天包括这一周开始学习AC自动机了,有点晚,但我感觉努努力还来得及.4月份还得认认真真攻图论,加油! 为2个月后的邀请赛及省赛.东北赛做准备. 推荐AC自动机学习地址:http://www.cppbl ...
- [AC自动机][学习笔记]
用途 AC自动机适用于一类用多个子串在模板串中匹配的字符串问题. 也就是说先给出一个模板串,然后给出一些子串.要求有多少个子串在这个模板串中出现过. KMP与trie树 其实AC自动机就是KMP与tr ...
随机推荐
- sublime 安装Anaconda插件 配置python开发环境
我的sublime 3 python 3.6.6 安装Anaconda插件 由于Anaconda插件本身无法知道Python安装的路径,所以需要设置Python主程序的实际位置.选择Settings ...
- ADO.NET中DataTable类的使用
DataTable类将关系数据表示为表格形式.在创建DataTable之前,必须包含System.Data名称空间.ADO.NET提供了一个DataTable类来独立创建和使用数据表.它也可以和Dat ...
- SpringBoot开始多线程
增加配置类 package com.springbootdemo.demo.config; import org.springframework.context.annotation.Bean; im ...
- webpack进阶(三)
1)CommonsChunkPlugin已经从webpack4移除,所以在用webpack进行公共模块的拆分时,会报错 Cannot read property 'CommonsChunkPlugin ...
- 纯C 实现 strpos substr strspilt str_trim
在C 语言中没有C++ 好用的 spilt 方法 (STL 带的也不怎么好用) #include <stdio.h> #include <string.h> #include ...
- 编译putty 源码去掉 Are you sure you want to close this session? 提示
0, 为什么要编译 putty ?在关闭窗口的时候,会弹出一个 Are you sure you want to close this session?要把这个去掉.当然也可以用 OD 之类的来修改. ...
- golang 学习之路 string转换为其他类型 其他类型转换为string
将其他值转换为string 一般常用fmt.Sprintf(格式,转换的值) // 使用fmt.Sprintf 转换所有的类型为string 使用 这是第一种 // 注意在sprintf使用中需要注意 ...
- 浅谈Java中静态代码块和非静态代码块
静态代码块: static{} 执行优先级高于非静态的初始化块,它会在类初始化(类初始化这个问题改天再详细讨论)的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员. 非静 ...
- .net webapi 接收保存图片到服务器,并居中剪裁压缩图片
原文链接:https:////www.cnblogs.com/Jackyye/p/12510943.html 每天解决一些c#小问题,在写微信小程序,或者一些手机软件接口,我们经常要用到上传图片到服务 ...
- 两个div,高度都是100% 用 display:flex; 和 min-height 一边撑高了,另一边自动走 (不加flex不自动撑开)
两个div,高度都是100% 用 display:flex; 和 min-height 一边撑高了,另一边自动走