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 ...
随机推荐
- PTA数据结构与算法题目集(中文) 7-16
PTA数据结构与算法题目集(中文) 7-16 7-16 一元多项式求导 (20 分) 设计函数求一元多项式的导数. 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000 ...
- 【php】错误日志处理
一. 错误处理: a) 在写程序的过程当中,遇到错误时,你的反应?可能比较急躁,比较烦 b) 遇到错误后:一别哭,二别闹,三别上吊,四别尿……二. 你可能会遇到的错误: a) 语法错误 i. 语法错误 ...
- linux 配置 python3 CGI
文章更新于:2020-03-04 注1:安装 python 参见: python 的安装使用和基本语法 注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务 ...
- docker 私有仓库 删除镜像
1.查找官方删除法 https://github.com/burnettk/delete-docker-registry-image 2.民用删除法 https://segmentfault.com/ ...
- C语言 文件操作(七)
C语言获取文件状态 stat() #include <sys/stat.h> #include <unistd.h> int stat(const char *file_nam ...
- 2020-3-15 20175110王礼博 Exp2后门原理与实践
目录 1.使用netcat获取主机操作Shell,cron启动 2.使用socat获取主机操作Shell, 任务计划启动 3.使用MSF meterpreter(或其他软件)生成可执行文件,利用nca ...
- 了解一下mock
1.mock简介: mock测试就是在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mo ...
- 使用StopWatch类来计时 (perf4j-0.9.16.jar 包里的类)
public class StopWatch { static public int AN_HOUR = 60 * 60 * 1000; static public int A_MINUTE = 60 ...
- 字符串的常用操作和方法(Python入门教程)
字符串的常用操作 很好理解 字符串可以用 ' + ' 连接,或者乘一个常数重复输出字符串 字符串的索引操作 通过一对中括号可以找到字符串中的某个字符 可以通过正负数双向操作噢 用一个中括号来实现 为什 ...
- 实现一个简单的基于动态代理的 AOP
实现一个简单的基于动态代理的 AOP Intro 上次看基于动态代理的 AOP 框架实现,立了一个 Flag, 自己写一个简单的 AOP 实现示例,今天过来填坑了 目前的实现是基于 Emit 来做的, ...