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自动机的更多相关文章

  1. 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机

    为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...

  2. Trie树&kmp&AC自动机&后缀数组&Manacher

    Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...

  3. 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 ...

  4. 关于Trie KMP AC自动机

    个人认为trie,KMP,AC自动机是思想非常明确的,AC自动机的性质是与KMP算法的思想类似的(失配后跳转) 而KMP是线性的,AC自动机是在tire树上跑KMP,为方便那些不会用指针的小朋友(我也 ...

  5. hdu1686 Oulipo KMP/AC自动机

    The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...

  6. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

  7. 优先队列 + 并查集 + 字典树 + 欧拉回路 + 树状数组 + 线段树 + 线段树点更新 + KMP +AC自动机 + 扫描线

    这里给出基本思想和实现代码 . 优先队列 : 曾经做过的一道例题       坦克大战 struct node { int x,y,step; friend bool operator <(no ...

  8. AC自动机【萌新文章】

    我这个蒟蒻第一次写博客,有点小激动呢. 主要是最近刚学了AC自动机,学得糟糟糕糕,记录一下,看到dalao们都在写博客,决定自己也写一波[我好水的啦,写的也不好] AC自动机大概就是    Trie+ ...

  9. 【BZOJ3940】【BZOJ3942】[Usaco2015 Feb]Censoring AC自动机/KMP/hash+栈

    [BZOJ3942][Usaco2015 Feb]Censoring Description Farmer John has purchased a subscription to Good Hoov ...

随机推荐

  1. 深入解读ES6系列(二)

    ES6函数 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,上一节说了es6的历史,变量,以及闭包,这一节我们继续我们知识的海洋,一起奋斗不秃头!不足的欢迎提问留言. 今 ...

  2. 新建基于STM32F103ZET6的工程-寄存器版本

    1.新建空白工程 新建一个文件夹,用来存放新建的工程文件.在这个新建的文件夹下创建MDK-PRO和OUTPUT两个子文件夹.MDK-PRO文件夹用来存放工程文件:OUTPUT用来存放工程编译器后输出的 ...

  3. PTA数据结构与算法题目集(中文) 7-8

    PTA数据结构与算法题目集(中文)  7-8 7-8 哈利·波特的考试 (25 分)   哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是 ...

  4. Nginx知多少系列之(三)配置文件详解

    目录 1.前言 2.安装 3.配置文件详解 4.Linux下托管.NET Core项目 5.Linux下.NET Core项目负载均衡 6.Linux下.NET Core项目Nginx+Keepali ...

  5. php人民币小写转大写函数,不限长度,精确到分

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ustb80.blog.51cto.com/6139482/1035327 在打印 ...

  6. Linux网络安全篇,认识防火墙(三),TCP Wrappers

    1.防火墙设置文件 任何以xinetd管理的服务都可以通过 /etc/hosts.allow /etc/hosts.deny 这两个文件来设置防火墙(针对源IP或域进行允许或操作的设置). 其实/et ...

  7. C语言数据结构栈

    #include<stdio.h>#include<stdlib.h>typedef struct Node{ int data; struct Node* pnext;}no ...

  8. Nuxt内导航栏的两种实现方式

    方式一 | 通过嵌套路由实现 在pages页面根据nuxt的路由规则,建立页面 1. 创建文件目录及文件 根据规则,如果要创建子路由,子路由的文件夹名字,必须和父路由名字相同 所以,我们的文件夹也为i ...

  9. 19cRAC增删节点

    由于测试环境打19c补丁失败,导致节点2  d2 crs无法启动!打补丁没有有效备份,亲人两行泪 先删再加节点. 一.删除节点 1.1 删除实例 参考 https://www.cnblogs.com/ ...

  10. String 对象-->概念和创建

    1.String 对象 String 对象用于处理文本(字符串). String 对象创建方法: new String(). 语法: var txt = new String("string ...