算法竞赛模板 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].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...
随机推荐
- Java数组遍历
1.数组声明格式: 数据类型 [] 数组名 = new 数据类型[长度]: 数组长度一旦确定无法更改. 数组里的数据必须是相同类型或自动向上转型后兼容的类型 2.数组遍历 //一维数组 String ...
- 对php引用的理解
/** * 引用是符号表别名 */ // $a与$b指向同一个变量 $a = &$b; // 定义函数foo,参数为引用类型:&$var,无函数体 function foo(& ...
- scroll兼容性
document.html=>document.documentElement function scroll() { if(window.pageYOffset != null) // ie9 ...
- JavaScript如何诞生
JavaScript之父谈语言诞生记 发表于2011-06-27 10:30| 9749次阅读| 来源ruanyifeng.com| 0 条评论| 作者阮一峰 prototypeprimitiveja ...
- tomcat如何正确的开启远程调试功能(转)
转自:http://blog.csdn.net/mhmyqn/article/details/49209541 版权声明:本文为博主原创文章,未经博主允许不得转载. 在日常开发中,有时需要对远程服务器 ...
- Node.js require 方法
Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同
- 转帖 移动端h5页面不同尺寸屏幕适配兼容方法
1. viewport属性及html页面结构 <meta name="viewport" content="width=device-width,initial ...
- java输出当前文件所在路径
System.out.println(System.getProperty("user.dir"));//user.dir指定了当前的路径
- Cesium鼠标事件
computed: { handler() { return new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas) } } ...
- 【leetcode】982. Triples with Bitwise AND Equal To Zero
题目如下: Given an array of integers A, find the number of triples of indices (i, j, k) such that: 0 < ...