一开始讲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. C++扬帆远航——3(打印图形)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:tuxing.cpp * 作者:常轩 * 完成日期:2016年3 ...

  2. Java并发编程(01):线程的创建方式,状态周期管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...

  3. .NET Core C#目录

    .NET Core技术开发指南 简介 本系列教程是一份关于微软.NET Core技术栈的全面的教程,其中涉及了C#.Typescript.Angular.Redis等一系列的教程.其中教程中通常会含有 ...

  4. 7-40 jmu-python-统计成绩 (15 分)

    输入一批学生成绩,计算平均成绩,并统计不及格学生人数. 输入格式: 每行输入一个数据,输入数据为负数结束输入 输出格式: 平均分=XX,不及格人数=XX,其中XX表示对应数据.如果没有学生数据,输出没 ...

  5. getUserMedia API及HTML5 调用手机摄像头拍照

    getUserMedia API简介 HTML5的getUserMedia API为用户提供访问硬件设备媒体(摄像头.视频.音频.地理位置等)的接口,基于该接口,开发者可以在不依赖任何浏览器插件的条件 ...

  6. Android html5 控制video currentTime不准确,精确,解决办法。

    早在flash时代 我们控制视频播放指定时间位置的画面也会有不准确的情况, 具体情况表现为:video.seek(time)   而实际画面会跳到此时间附近(1-2秒)的画面 而HTML5 我们通过 ...

  7. Linux中软连接和硬连接的区别

    首先,我们要清楚符号链接的目的,在不改变原目录/文件的前提下,起一个方便的别名(在这起个别名,让我想到前阶段学C里typedef也是起别名的). 1.软连接就相当于windows的快捷方式.例如:ln ...

  8. Java堆内存是线程共享的!面试官:你确定吗?

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  9. 2020年ubuntu sever1804 安装和配置

    最后一次折腾linux服务器,应该是13的我的VPS.因为转行后,没有及时关注vps续费的问题,结果过期,所有的数据丢失了 当时觉得,反正都不做了,丢了就丢了吧,可现在想起来,实在是太后悔了. 今天, ...

  10. Linux环境下安装MySQL 5.7.28

    先进入MySQL官网: www.mysql.com 去下载安装包 进入DOWNLOADS选项,点击MySQL Community (GPL) Downloads. 点击进入MySQL Communit ...