KMP & AC自动机
KMP
void kmp(char t[],char p[])
{
int n=strlen(t),m=strlen(p);
int *f=new int[m];
f[0]=f[1]=0;
for(int i=1;i<m;++i)
{
int j=f[i];
while(j&&p[i]!=p[j])j=f[j];
f[i+1]=p[j]==p[i]?j+1:0;
}
for(int i=0,j=0;i<n;++i)
{
while(j&&t[i]!=p[j])j=f[j];
if(t[i]==p[j])j++;
if(j==m)printf("%d\n",i-m+1);
}
delete[] f;
}
Aho-Corasick automa
Trie + fail[] & last[] + matching
int fail[int i]
失配函数,注意i和fail[i]结点对应的字母相同;f[0]=0,f[ch[0][u]]=0。
int last[int i]
沿失配函数往回走遇到的第一个单词结点。(可选)
输出所有与前i位的后缀匹配的单词的val值
可能有错
const int maxn=1e6+5;
struct trie
{
int ch[500010][26],val[maxn],fail[maxn],last[maxn];
int sz;
trie(){sz=0;ms(ch[0],0);}
void Insert(char s[],int v)
{
int u;for(u=0;*s;++s){if(!ch[u][*s-'a']){ch[u][*s-'a']=++sz;ms(ch[sz],0);}u=ch[u][*s-'a'];val[u]=0;}
val[u]=v;
}
void GetFailLast()
{
queue<int> q;while(!q.empty())q.pop();q.push(0);fail[0]=0;for(int i=0;i<26;++i)fail[ch[0][i]]=0;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<26;++i)
{
int v=ch[u][i],t=fail[u];;if(!v)continue;
q.push(v);
while(t&&!ch[t][i])t=fail[t];
fail[v]=ch[t][i];last[v]=val[fail[v]]?fail[u]:last[fail[v]];
}
}
}
void Query(char s[])
{
for(int u=0,i=0;*s;s++,i++){while(u&&!ch[u][*s-'a'])u=fail[u];u=ch[u][*s-'a'];int tmp=val[u]?u:last[u];while(tmp)printf("%d %d\n",i,val[tmp]),tmp=last[tmp];}
}
}T;
另一版本
ch[][]
给出了自动机状态转移图的完整邻接表- 加上根结点一共
sz
个结点,其中根结点标号为0,其余分别为1,...,sz-1 - 查询时,每一步都需要沿
fail[]
往回检查 - -1表示结点不存在(用memset初始化是可行的。memset可以初始化0和-1)
const int sigma_size=26,max_node=100;
struct Trie
{
int ch[max_node][sigma_size],val[max_node],fail[max_node],sz;
int newnode(){memset(ch[sz],-1,sizeof ch[sz]);val[sz]=0;return sz++;}
void init(){sz=0;newnode();}
void insert(char s[],int v)
{
int u;for(u=0;*s;++s){if(ch[u][*s-'a']==-1)ch[u][*s-'a']=newnode();u=ch[u][*s-'a'];}
val[u]=v;
}
void build()
{
queue<int>q;
for(int i=0;i<sigma_size;++i)
{
int &v=ch[0][i];
if(v==-1)v=0;
else {fail[v]=0;q.push(v);}
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<sigma_size;++i)
{
int &v=ch[u][i];
if(v==-1)v=ch[fail[u]][i];
else{fail[v]=ch[fail[u]][i];q.push(v);}
}
}
}
void query(char s[])
{
for(int u=0,t,cnt=0;*s;++s,++cnt)
{
t=u=ch[u][*s-'a'];
while(t){if(val[t])printf("%d %d\n",cnt,val[t]);t=fail[t];}
}
}
}T;
KMP & AC自动机的更多相关文章
- 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机
为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...
- Trie树&kmp&AC自动机&后缀数组&Manacher
Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...
- 2021.11.09 P4824 [USACO15FEB]Censoring S与P3121 [USACO15FEB]Censoring G(KMP&&AC自动机)
2021.11.09 P4824 [USACO15FEB]Censoring S与P3121 [USACO15FEB]Censoring G(KMP&&AC自动机) https://w ...
- 关于Trie KMP AC自动机
个人认为trie,KMP,AC自动机是思想非常明确的,AC自动机的性质是与KMP算法的思想类似的(失配后跳转) 而KMP是线性的,AC自动机是在tire树上跑KMP,为方便那些不会用指针的小朋友(我也 ...
- hdu1686 Oulipo KMP/AC自动机
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...
- 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组
题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...
- 优先队列 + 并查集 + 字典树 + 欧拉回路 + 树状数组 + 线段树 + 线段树点更新 + KMP +AC自动机 + 扫描线
这里给出基本思想和实现代码 . 优先队列 : 曾经做过的一道例题 坦克大战 struct node { int x,y,step; friend bool operator <(no ...
- AC自动机【萌新文章】
我这个蒟蒻第一次写博客,有点小激动呢. 主要是最近刚学了AC自动机,学得糟糟糕糕,记录一下,看到dalao们都在写博客,决定自己也写一波[我好水的啦,写的也不好] AC自动机大概就是 Trie+ ...
- 【BZOJ3940】【BZOJ3942】[Usaco2015 Feb]Censoring AC自动机/KMP/hash+栈
[BZOJ3942][Usaco2015 Feb]Censoring Description Farmer John has purchased a subscription to Good Hoov ...
随机推荐
- 牛客寒假基础集训营 | Day1 G-eli和字符串
G-eli和字符串 题目描述 eli拿到了一个仅由小写字母组成的字符串. 她想截取一段连续子串,这个子串包含至少 kkkkkkkkk 个相同的某个字母. 她想知道,子串的长度最小值是多少? 注:所谓连 ...
- Boxes Packing
Boxes Packing Mishka has got n empty boxes. For every i (1 ≤ i ≤ n), i-th box is a cube with side le ...
- SpringBoot整合Springfox-Swagger2
前言 不管Spring Boot整合还是SpringMVC整合Swagger都基本类似,重点就在于配置Swagger,它的精髓所在就在于配置. @ 目录 1.Swagger简介 2.整合前可能遇到的问 ...
- 3.26java作业
1.编写程序, 输入变量x的值,如果是1,输出x=1,如果是5,输出x=5,如果是 10,输出 x=10,除了以上几个值,都输出x=none.(知识点:if条件语句) package fda; imp ...
- 面试总结:关于MySQL事务的10个问题常见面试问答(FQA)
学习关系型数据库MySQL是很好的切入点,大部分人工作中用惯了CRUD,对面试官刨根问底的灵魂拷问你还能对答如流吗?我们有必要了解一些更深层次的数据库基础原理. 文章每周持续更新,各位的「三连」是对我 ...
- Java内存可见性volatile
概述 JMM规范指出,每一个线程都有自己的工作内存(working memory),当变量的值发生变化时,先更新自己的工作内存,然后再拷贝到主存(main memory),这样其他线程就能读取到更新后 ...
- mybatis源码配置文件解析之一:解析properties标签
mybatis作为日常开发的常用ORM框架,在开发中起着很重要的作用,了解其源码对日常的开发有很大的帮助.源码版本为:3-3.4.x,可执行到github进行下载. 从这篇文章开始逐一分析mybati ...
- 如何用VmwareWorkstation安装Centos系统
教你如何安装虚拟机系统 首先你得有虚拟化软件,常用的VmwareWorkstation一般能满足日常需求. 下载地址,请自行搜索. 第一步,新建虚拟机 选择安装系统源 这里有三个选项. 1.第一个是使 ...
- python socket简介
一.socket是什么 socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP协议隐藏在socket接口后面, ...
- linux之进程管理(二)
一.查看进程 ps aux 查看系统所有的进程数据 ps -lA 查看所有系统的数据 ps axjf 连同部分进程树状态 ps参数 -A 显示所有进程,等效 -e -a 不与ter ...