Aho_Corasick自动机(AC自动机)

首先,AC自动机不是Accept自动机,别以为把这段代码复制到OJ上就全都自动AC了……

其实这玩意是Aho-Corasick 造出来的,所以你懂的。

那么这玩意能干嘛咧?

•字符串的匹配问题

•多串的匹配问题※

看不懂吧?解释一下:

例如给几个单词 acbs,asf,dsef,再给出一个 很长的文章,acbsdfgeasf,问在这个文章中,总共出现了多少个单词,或者是单词出现的总次数。

怎么实现的呢,就是KMP+trie树。是以KMP为算法基础,trie为索引结构的东东。那它如何与kmp联系在一起?

•关键是在trie树上加了一种fail指针。

•Fail指针的用途:就像是kmp中的next的数组。

在字符串失配的时候确定转移的节点。AC难点就是指针的算法,看下面这么多图:

模板:

 1 struct Aho_Corasick{
 2     int ch[maxn][Sigc], ms;
 3     int val[maxn], f[maxn], len[maxn];
 4     int last[maxn];
 5     Aho_Corasick(){}
 6     void init(){
 7         ms = 0;
 8         memset(val, 0, sizeof(val));
 9         memset(ch, 0, sizeof(ch));
10         memset(f, 0, sizeof(f));
11         memset(last, 0, sizeof(last));
12         memset(len, 0, sizeof(len));
13         return ;
14     }
15     void insert(char* s, int v){
16         int cur = 0, i;
17         for(i = 0; s[i] != ‘\0‘; i ++){
18             int c = s[i] - ‘0‘;
19             if(!ch[cur][c]) ch[cur][c] = ++ ms; // 1
20             cur = ch[cur][c];
21         }
22         val[cur] = v; len[cur] = i;
23         return ;
24     }
25     void make_fail(){
26         queue<int> Q;
27         for(int i = 0; i < Sigc; i ++) if(ch[0][i]) Q.push(ch[0][i]);
28         while(!Q.empty()){
29             int x = Q.front(); Q.pop();
30             for(int c = 0; c < 2; c ++){
31                 int v = ch[x][c];
32                 if(!v) { ch[x][c] = ch[f[x]][c]; continue; }
33                 Q.push(v);
34                 int cur = f[x];
35                 while(cur && !ch[cur][c]) cur = f[cur];
36                 f[v] = ch[cur][c];
37                 last[v] = val[f[v]] ? f[v] : last[f[v]];
38             }
39         }
40         return ;
41     }
42 };
时间: 2024-10-27 01:13:16

Aho_Corasick自动机(AC自动机)的相关文章

AC自动机 - AC自动机 - 多模式串的匹配运用 --- HDU 3065

病毒侵袭持续中 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Mean: 中文题,不解释. analyse: AC自动机的运用.这一题需要将模式串都存储下来,还有就是base的取值一定要弄清楚,由于这题的模式串都是大写字母所以我们可以通过剪枝来加速. Time complexity:o(n)+o(ml)  Source code: // Memory Time // 1347K 0MS // by : Snarl_js

BZOJ 题目3172: [Tjoi2013]单词(AC自动机||AC自动机+fail树||后缀数组暴力||后缀数组+RMQ+二分等五种姿势水过)

3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1890  Solved: 877 [Submit][Status][Discuss] Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词由小写字母组成,N<=200,单词长度不超过10^6

从Trie谈到AC自动机

ZJOI的SAM让我深受打击,WJZ大神怒D陈老师之T3是SAM裸题orz...我还怎么混?暂且写篇`从Trie谈到AC自动机`骗骗经验. Trie Trie是一种好玩的数据结构.它的每个结点存的是字母,因此得名`字母树`. 出一张图让大家感受下. (image powered by SaiBu NaoCu) 上面那是一棵插入了 ape,app,applicant,application,bake,ban,banana 等词的Trie.红色结点表示接受态. 显然,查找时只需顺着链照下来,插入只需

多模字符串匹配算法之AC自动机—原理与实现

简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上是KMP算法的树形扩展.这篇文章主要介绍AC自动机的工作原理,并在此基础上用Java代码实现一个简易的AC自动机. 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 应用场景-多模字符串匹配 我们现在考虑这样一个问题,在一个文本串t

AC自动机算法及模板

关于AC自动机 AC自动机:Aho-Corasickautomation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过.要搞懂AC自动机,先得有模式树(字典树)Trie和KMP模式匹配算法的基础知识.AC自动机算法分为3步:构造一棵Trie树,构造失败指针和模式匹配过程. 简单来说,AC自动机是用来进行多模式匹配(单个主串,多个模式串)的高效算法. AC自动机的构造过程 使用Aho-

【暑假】[实用数据结构] AC自动机

Aho-Corasick自动机 AC自动机用于解决文本一个而模板有多个的问题. 作者所给模板如下: 1 struct AhoCorasickAutomata { 2 int ch[MAXNODE][SIGMA_SIZE]; 3 int f[MAXNODE]; // fail函数 4 int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val 5 int last[MAXNODE]; // 输出链表的下一个结点 6 int cnt[MAXS]; 7 int sz; 8 9

[leetcode] 1032: Stream of Characters: Tries&amp;AC自动机

其实这道题好像大部分人都直接用Tries倒序来解,但我觉得AC自动机可能更高效一点(毕竟是在Tries基础上优化的算法如果还不如原始Tries似乎说不过去). 根据定义写了个原始的在堆上创建树形结构的solution但好像性能并不是很乐观.另外一些用AC解的dalao好像是用一条线性结构存储所有结点再用指针记录树种结点的连接关系,理解起来相对复杂一些但这样性能应该会比原始的树形结构提升很多. Tries 根据设定的字典中所有单词创建的字典树,对输入字符串的匹配过程就是对tries的遍历.如果某个

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <

hdu 2896 AC自动机

// hdu 2896 AC自动机 // // 题目大意: // // 给你n个短串,然后给你q串长字符串,要求每个长字符串中 // 是否出现短串,出现的短串各是什么 // // 解题思路: // // AC自动机,插入单词,构建自动机,然后查询就可以了. // // 感悟: // // 哎,自己AC自动机果然刚学,还只会个模板,自动机构没构建 // 都不知道...继续加油吧~~~FIGHTING! #include <cstdio> #include <cstring> #inc