Aho_Corasick自动机(AC自动机)
首先,AC自动机不是Accept自动机,别以为把这段代码复制到OJ上就全都自动AC了……
在字符串失配的时候确定转移的节点。AC难点就是指针的算法,看下面这么多图:










#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define REP(i, s, n) for(int i = s; i <= n; i ++)
#define RAP(i, n, s) for(int i = n; i >= s; i --)
#define now ch[x][c]
using namespace std;
const int maxn = + ;
const int maxsig = ;
char S[ + ];
int n;
inline void read(int &x){
x = ; int sig = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') sig = -; ch = getchar(); }
while(isdigit(ch)) x = * x + ch - '', ch = getchar();
x *= sig; return ;
}
inline void write(int x){
if(x == ) { putchar(''); return; }
if(x < ) putchar('-'), x = -x;
int len = , buf[];
while(x) buf[len ++] = x % , x /= ;
RAP(i, len - , ) putchar(buf[i] + ''); return ;
}
namespace Aho_Corasick{
int ch[maxn][maxsig], val[maxn], f[maxn], last[maxn], len[maxn], ms;
void AC_init(){
ms = ;
memset(ch, , sizeof(ch));
memset(val, , sizeof(val));
memset(f, , sizeof(f));
memset(last, , sizeof(last));
memset(len, , sizeof(len));
return ;
}
void insert(char* s, int v){
int x = , i;
for(i = ; s[i] != '\0'; i ++){
int c = s[i] - ''; if(!now) now = ++ ms; x = now;
}
val[x] = v; len[x] = i; return ;
}
void getfail(){
queue<int> Q;
REP(i, , maxsig - ) if(ch[][i]) Q.push(ch[][i]);
while(!Q.empty()){
int x = Q.front(); Q.pop();
REP(c, , maxsig - ){
if(!now) { now = ch[f[x]][c]; continue; }
Q.push(now); int cur = f[x];
while(cur && !now) cur = f[cur];
f[now] = ch[cur][c]; last[now] = val[f[now]] ? f[now] : last[f[now]];
}
}
return ;
}
void AC_print(int i, int j){
if(j){
write(val[j]); printf(": ");
write(i - len[j] + ); printf(" to ");
write(i); putchar('\n');
AC_print(i, last[j]);
}
return ;
}
void solve(char* T){
int cur = ;
for(int i = ; T[i] != '\0'; i ++){
cur = ch[cur][T[i] - ''];
if(val[cur]) AC_print(i, cur);
else if(last[cur]) AC_print(i, last[cur]);
}
return ;
}
}using namespace Aho_Corasick;
bool init(){
read(n); if(!n) return false;
AC_init();
REP(i, , n) scanf("%s", S), insert(S, i);
return true;
}
void work(int cur){
getfail();
scanf("%s", S);
printf("Case "); write(cur);
printf(":\n");
solve(S);
return ;
}
void print(){ return ;
}
int main(){
int Case = ;
while(init()) work(Case ++);
return ;
}
Aho_Corasick自动机(AC自动机)的更多相关文章
- 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...
- 从Trie谈到AC自动机
ZJOI的SAM让我深受打击,WJZ大神怒D陈老师之T3是SAM裸题orz...我还怎么混?暂且写篇`从Trie谈到AC自动机`骗骗经验. Trie Trie是一种好玩的数据结构.它的每个结点存的是字 ...
- 多模字符串匹配算法之AC自动机—原理与实现
简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...
- AC自动机详解(附加可持久化AC自动机)
AC自动机 AC自动机,说白了就是在trie树上跑kmp(其实个人感觉比kmp容易理解).是一种多匹配串,单个主串的匹配.概括来说,就是将多个匹配串构造一个trie树,对于每个trie树的节点构造nx ...
- 浅谈算法——AC自动机
在学习AC自动机之前,你需要两个前置知识:Trie树,KMP 首先我们需要明白,AC自动机是干什么的(用来自动AC的) 大家都知道KMP算法是求单字符串对单字符串的匹配问题的,那么多字符在单字符上匹配 ...
- [Alg] 文本匹配-多模匹配-AC自动机
1. 简介 AC自动机是一种多模匹配的文本匹配算法. 如果采用naive的方法,即依次比较文本串s中是否包含模式串p1, p2,...非常耗时.考虑到这些模式串中可能具有相同子串,可以利用已经比较过的 ...
- 字典树基础进阶全掌握(Trie树、01字典树、后缀自动机、AC自动机)
字典树 概述 字典树,又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它 ...
- hdu 2896 AC自动机
// hdu 2896 AC自动机 // // 题目大意: // // 给你n个短串,然后给你q串长字符串,要求每个长字符串中 // 是否出现短串,出现的短串各是什么 // // 解题思路: // / ...
- hdu 3065 AC自动机
// hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建, ...
随机推荐
- js中return false,return,return true的使用方法及区别
起首return作为返回keyword,他有下面两种返回体式格式 1.返回把握与函数成果 语法为:return 表达式; 语句停止函数履行,返回调用函数,而且把表达式的值作为函数的成果 2.返回把握无 ...
- CSS控制LI行字符溢出用省略号取代
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 第二篇:Power BI数据可视化之基于Web数据的报表制作(经典级示例)
前言 报表制作流程的第一步显然是从各个数据源导入数据,Power BI能从很多种数据源导入数据:如Excel,CSV,XML,以及各类数据库(SQL Server,Oracle,My SQL等),两大 ...
- Java基础知识强化之集合框架笔记10:Collection集合使用的步骤
集合使用的步骤: (1)创建集合对象 (2)创建元素对象 (3)把元素添加到集合 (4)遍历集合: • 通过集合对象获取迭代器对象 • 通过迭代器对象的hasnext()方法判断是否有元素 ...
- HeaderViewListAdapter
该类其实就是普通使用的Adapter的一个包装类,就是为了添加header和footer而定义的.该类一般不直接使用,当ListView有header和footer时,ListView中会自动把Ada ...
- RHEL7下PXE+NFS+Kickstart无人值守安装操作系统
RHEL7下PXE+NFS+Kickstart无人值守安装操作系统 1.配置yum源 vim /etc/yum.repos.d/development.repo [development] name= ...
- HDU 5033 Building(单调栈维护凸包)
盗张图:来自http://blog.csdn.net/xuechelingxiao/article/details/39494433 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度, ...
- android 安全退出应用程序的几种方法
android 安全退出应用程序的几种方法 正常关闭应用程序: 当应用不再使用时,通常需要关闭应用,可以使用以下三种方法关闭android应用: 第一种方法:首先获取当前进程的id,然后杀死该进程.a ...
- 加速器eaccelerator不兼容高版本php
话说PHP官方发布PHP5.4已经有一阵了,根据使用的情况来看,似乎还是很不错的.从初始发布到现在升级到的PHP5.4.4,修正不少的Bug.PHP5.4新的版本,除了提供了更多新的特性,还有大幅的效 ...
- 抓取锁的sql语句-第三次修改
CREATE OR REPLACE PROCEDURE SOLVE_LOCK AS V_SQL VARCHAR2(3000); --定义 v_sql 接受抓取锁的sql语句CUR_LOCK SYS_R ...