算法竞赛模板 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].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...
随机推荐
- 如何使用 VLD 检测程序中的内存泄漏?
下载地址:https://kinddragon.github.io/vld/ 下载 windows 安装包,进行安装即可,它会给你设置好 vs 的环境变量,使用时,直接在 vs ide 中包含即可. ...
- fieldset与legend,label
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 从现在开始强迫自己使用 Reflect
静态方法 Reflect.apply(target, thisArg, args) 等同于 Function.prototype.apply.call(func, thisArg, args) Ref ...
- android 短信发送
- 更改mysql最大连接数
方法一: 打开cmd,用"mysql -u root -p;"命令进入mysql, 输入命令:show variables like "max_connections&q ...
- 【记录】linux 命令拷贝文件到远程服务器,linux下载文件到本地
Linux scp命令用于Linux之间复制文件和目录 -1 强制scp命令使用协议ssh1 -2 强制scp命令使用协议ssh2 -4 强制scp命令只使用IPv4寻址 -6 强制scp命令只使用I ...
- 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...
- Python 第三天学习整理2
一.常用的字符串方法 capitalize() #将字符串首字母大写 center(100,'*') #把字符串居中的 count(‘zhou’)#查询次数 endswith('.jpg ')#判断字 ...
- 20.ReenterLock重入锁
import java.util.concurrent.locks.ReentrantLock; /** * 重入锁 ReenterLock 一个线程允许连续获得同一把锁,注意:必须释放相同次数,释放 ...
- 如何给 List 集合排序
一,List<Integer>的排序示例代码:List<Integer> list = new ArrayList<Integer>();list.add(6);l ...