算法竞赛模板 AC自动机
AC自动机基本操作
(1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针。
(2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思义,就是当匹配失败的时候,用于引导p指针回溯,就和KMP算法中的next数组道理相同。
#include<bits/stdc++.h>
using namespace std;
#define MAX 26 //字典树关键字为‘a’~‘b’
char str[]; //主串(文章)
int n; //模式串共有n串 //字典树结点定义
struct Node
{
Node*next[MAX];
Node*fail;
int sum;
}*qu[]; void init(Node*root)
{
for(int i=;i<MAX;i++)
root->next[i]=NULL;
} //向字典树内添加模式串
void Insert(Node*root,char*ch)
{
Node*p=root;
while(*ch)
{
int index=*ch-'a';
if(p->next[index]==NULL)
{
p->next[index]=(Node*)malloc(sizeof(Node));
init(p->next[index]);
p->next[index]->sum=;
}
p=p->next[index];
ch++;
}
p->sum++;
} //利用模式串 字典树建树
Node*TrieCreate()
{
char ch[];
Node*root=(Node*)malloc(sizeof(Node));
init(root);
for(int i=;i<n;i++)
{
scanf("%s",ch);
Insert(root,ch);
}
return root;
} //在字典树内构建 失配指针fail
void BuildFail(Node*root)
{
int head=,tail=,i;
root->fail=NULL;
qu[tail++]=root;
while(head<tail)
{
Node*t=qu[head++];
Node*p=NULL;
for(i=;i<;i++)
{
if(t->next[i])
{
if(t==root)
t->next[i]->fail=root;
else
{
p=t->fail;
while(p)
{
if(p->next[i])
{
t->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(!p)
t->next[i]->fail=root;
}
qu[tail++]=t->next[i];
}
}
}
} //AC自动机 ,返回主串中模式串的数量(文章中关键字的数量)
int AC(Node*root,char*str)
{
int len=strlen(str),cnt=;
Node*p=root;
while(*str)
{
while(p->next[*str-'a']==NULL&&p!=root)p=p->fail;
p=p->next[*str-'a'];
p=(p==NULL)?root:p;
Node*t=p;
while(t!=root&&t->sum!=-)
{
cnt+=t->sum;
t->sum=-;
t=t->fail;
}
str++;
}
return cnt;
}
int main()
{
cin>>n;
Node*root=TrieCreate();
scanf("%s",str);
BuildFail(root);
printf("%d\n",AC(root,str));
return ;
}
算法竞赛模板 AC自动机的更多相关文章
- 算法模板——AC自动机
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...
- 算法总结篇---AC自动机
目录 写在前面 算法流程 引例: 概述: Trie树的构建(第一步) 失配指针(第二步) 构建失配指针 字典树和字典图 多模式匹配 例题 写在前面 鸣谢: OiWiki 「笔记」AC 自动机---Lu ...
- luoguP3808[模板]AC自动机(简单版)
传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...
- luoguP3796[模板]AC自动机(加强版)
传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...
- 模板 AC自动机
题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...
- 洛谷.3808/3796.[模板]AC自动机
题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...
- 算法竞赛模板 KMP
KMP算法图解: ① 首先,字符串“BBC ABCDAB ABCDABCDABDE”的第一个字符与搜索词“ABCDABD”的第一个字符,进行比较.因为B与A不匹配,所以搜索词后移一位. ② 因为B与A ...
- 模板—AC自动机
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct ...
- 算法竞赛模板 动态规划之背包DP
① 01背包 有n件物品和一个容量为v的背包.第i件物品的价值是c[i],体积是w[i].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...
随机推荐
- vue - blog开发学7
将基本的项目部署到linux上(前后台只是实现了基本的功能,本次只是记录一些基本的开发流程,完善,等后续) 1.linux环境准备(我用的是阿里云服务器) ①jre.mysql,Nginx基本上这些就 ...
- 57.Queue Reconstruction by Height(按身高重建对列)
Level: Medium 题目描述: Suppose you have a random list of people standing in a queue. Each person is d ...
- js非数值的比较
/** * 非数值的比较: * 1.对于非数值的比较时,会将其转换成数字然后再比较 * 2.如果符号两端是字符串的值进行比较时,不会将其转换为数字进行比较,而是 * 分别比较字符串中的字符的 unic ...
- c# 编程--基础部分补全篇
C#基础 分支: switch switch(表达式) { case 具体值1: ...
- for循环(foreach型)举例
- [Js代码风格]浅析模块模式
1.实例解释模块模式 简明扼要的说,经典的模块模式指的定义一个立即执行的匿名函数.在函数中定义私有函数和私有变量并且返回一个包含公共变量和公共函数作为属性和方法的匿名对象. var classicMo ...
- proxy汇总-1
1.apt-get的proxy 新建/etc/apt/apt.conf.d目录下新建10proxy文件,添加: Acquire::http::proxy"http://xx.xx.xx.xx ...
- array_reduce — 用回调函数迭代地将数组简化为单一的值
定义和用法 array_reduce() 函数向用户自定义函数发送数组中的值,并返回一个字符串. 注释:如果数组是空的且未传递 initial 参数,该函数返回 NULL. 说明 array_redu ...
- 2.第一个Codefirst实例
1.什么是codefirst EF4.1中开始支持Code First .这种方式在领域设计模式中非常有用.使用Code First模式,你可以专注于领域设计,根据需要,为你一个领域的对象创建类集合, ...
- Selenium之XPATH定位方法
转自 https://www.cnblogs.com/hanmk/p/8997786.html https://www.cnblogs.com/hanmk/p/9015502.html 感谢原作者 1 ...