AC自动机
来源:互联网 发布:cs6软件下载 编辑:程序博客网 时间:2024/05/20 18:03
不要问我为什么刚写这个东西。
AC自动机=trie+KMP
【说实话KMP我都不太会写】
(Goes型备注版代码最适合G.S.M.学习了)
AC自动机模板:
简单版:(洛谷P3808)
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入格式:
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#if 0Writers: G.S.M. && Goes#endifstruct ss{ int fail,vis[27],end; //fail指针 该点的儿子有没有i 以该点做结尾的模串的个数}AC[1000005];int cnt=0;//trie的指针inline void build(string s){ int len=s.length();int now=0; for(int i=0;i<len;i++){ if(!AC[now].vis[s[i]-'a'])//如果没有这个子节点 AC[now].vis[s[i]-'a']=++cnt;//就把它构造出来 now=AC[now].vis[s[i]-'a'];//向下构造 }AC[now].end+=1; return ;//一串一串地往里面加}inline void Get_fail(){ queue < int > Q ; for ( int i = 0 ; i < 26 ; i ++ ) if( AC[0].vis[i] ) {//单独处理 第二层的fail指针 AC[AC[0].vis[i]].fail=0; Q.push(AC[0].vis[i]); } while(!Q.empty()){ int pos=Q.front();Q.pop(); for(int i=0;i<26;i++)//枚举所有字母 if( AC[pos].vis[i] ){//如果存在该子节点 AC[ AC[pos].vis[i] ].fail = AC[ AC[pos].fail ].vis[i]; Q.push(AC[pos].vis[i]); } else AC[pos].vis[i]=AC[AC[pos].fail].vis[i]; }}inline int query(string s){//求解 int len=s.length();int now=0,ans=0; for(int i=0;i<len;i++){ now=AC[now].vis[s[i]-'a']; for(int t=now;t&&AC[t].end!=-1;t=AC[t].fail) ans+=AC[t].end,AC[t].end=-1; }return ans;}int main(){ int n;string s;cin>>n; for(int i=1;i<=n;i++){ cin>>s;build(s); }//构造字典树trie AC[0].fail=0;Get_fail(); //fail指针(类似KMP的nex指针) cin>>s;printf("%d\n",query(s)); return 0;}
阅读全文
0 0
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- Sublime Text 3快捷键汇总
- 大型博客推广专家(商业版) 免费破解版
- 深入理解JVM(二)——内存模型、可见性、指令重排序
- java实现邮件发送, 抄送及多附件发送
- python实现简单的switch功能
- AC自动机
- NoSql介绍和入门
- Leetcode Valid Parentheses 解题报告
- 200. Number of Islands
- 函数、随机数、生成器与迭代器
- Java设计模式-责任链模式
- JAVA中的命名规则
- [javase]接口的工厂模式
- 账号注册邮箱激活设计