AC自动机 专题
// 求目标串中出现了几个模式串
//====================
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
using namespace std; struct Trie
{
int next[][],fail[],end[];
int root,L;
int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = ;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = ;i < len;i++)
{
if(next[now][buf[i]-'a'] == -)
next[now][buf[i]-'a'] = newnode();
now = next[now][buf[i]-'a'];
}
end[now]++;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;i++)
if(next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while( !Q.empty() )
{
int now = Q.front();
Q.pop();
for(int i = ;i < ;i++)
if(next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
int query(char buf[])
{
int len = strlen(buf);
int now = root;
int res = ;
for(int i = ;i < len;i++)
{
now = next[now][buf[i]-'a'];
int temp = now;
while( temp != root )
{
res += end[temp];
end[temp] = ;
temp = fail[temp];
}
}
return res;
}
void debug()
{
for(int i = ;i < L;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
for(int j = ;j < ;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
}
};
char buf[];
Trie ac;
int main()
{
int T;
int n;
scanf("%d",&T);
while( T-- )
{
scanf("%d",&n);
ac.init();
for(int i = ;i < n;i++)
{
scanf("%s",buf);
ac.insert(buf);
}
ac.build();
scanf("%s",buf);
printf("%d\n",ac.query(buf));
}
return ;
}
//输出每个模式串出现的次数 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std; char str[][];
struct Trie
{
int next[*][],fail[*],end[*];
int root,L;
int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = -;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(char s[],int id)
{
int len = strlen(s);
int now = root;
for(int i = ;i < len;i++)
{
if(next[now][s[i]] == -)
next[now][s[i]] = newnode();
now = next[now][s[i]];
}
end[now] = id;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;i++)
if(next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
for(int i = ;i < ;i++)
if(next[now][i] == -)
next[now][i]=next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
int num[];
void query(char buf[],int n)
{
for(int i = ;i < n;i++)
num[i] = ;
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++)
{
now=next[now][buf[i]];
int temp = now;
while( temp != root )
{
if(end[temp] != -)
num[end[temp]]++;
temp = fail[temp];
}
}
for(int i = ;i < n;i++)
if(num[i] > )
printf("%s: %d\n",str[i],num[i]);
} }; char buf[];
Trie ac;
void debug()
{
for (int i = ; i < ac.L; i++)
{
printf("id = %3d ,fail = %3d ,end = %3d, chi = [",i,ac.fail[i],ac.end[i]);
for (int j = ; j < ; j++)
printf("%2d ",ac.next[i][j]);
printf("]\n");
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
while(scanf("%d",&n) == )
{
ac.init();
for(int i = ;i < n;i++)
{
scanf("%s",str[i]);
ac.insert(str[i],i);
}
ac.build();
scanf("%s",buf);
ac.query(buf,n);
}
return ;
}
转自bin神 orz
AC自动机 专题的更多相关文章
- AC自动机专题
AC自动机简介:KMP是用于解决单模式串匹配问题, AC自动机用于解决多模式串匹配问题. 精华:设这个节点上的字母为C,沿着他父亲的失败指针走,直到走到一个节点,他的儿子中也有字母为C的节点.然后把当 ...
- AC自动机专题总结
最近学习了AC自动机,做了notonlysuccess大牛里面的题,也该来个总结了. AC自动机(Aho-Corasick Automaton)在1975年产生于贝尔实验室,是著名的多模匹配算法之一. ...
- 【原创】AC自动机小结
有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配. AC自动机 其实 就是创建了一个状态的转移图,思想很 ...
- AC自动机(AC automation)
字典树+KMP 参考自: http://www.cppblog.com/mythit/archive/2009/04/21/80633.html ; //字典大小 //定义结点 struct node ...
- 转自kuangbin的AC自动机(赛前最后一博)
有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配. AC自动机 其实 就是创建了一个状态的转移图,思想很 ...
- HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
- [专题总结]AC自动机
其实前面的模板也不是1A,我在题库里提前做过,也不必在意罚时,刚开始我在做别的专题 裸模板我就不说了,各个博客讲解的很明白 void insert(string s){ ,len=s.size(); ...
- [专题汇总]AC自动机
1.The 2011 ACM-ICPC Asia Dalian Regional Contest ZOJ 3545 Rescue the Rabbit 简单的AC自动机+状压DP, 状态DP[nod ...
随机推荐
- python错误集锦
1.lt与list等同,不能作为变量名 2.中文路径名:os.path.normcase(filepath) 如果遇到 ascii码在路径某处不能转换, 那么 filepath.encode('gbk ...
- HDU 1698 Just a Hook
题意:初始1-n 值为1,有Q操作,每次可以把一段[l,r] 整段每个值变成 x,问最后的[1,n]总和. 线段树成段更新(基础题) #include<cstdio> #include&l ...
- 二模 (4)day2
第一题: 题目大意:给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. N<=100000 1.考虑到一个符合要求的连 ...
- 常州培训 day4 解题报告
第一题:(简单的模拟题) 给出一个N位二进制数,有‘+’, ‘-’, ‘*’, ‘/’ 操作,分别表示加1,减1,乘2,除以2,给出M个操作,求出M个操作后的二进制数.N,M<=5000000; ...
- C# SQLiteDataReader获得数据库指定字段的值
获得数据库指定字段的值,赋给本地变量 (1)如下,获得userinfo数据表里的字段"userid"."orgid", string userid=" ...
- php判断用户浏览器类型是否为微信浏览器
PHP方法:利用PHP的“_SERVER ”数组“HTTP_USER_AGENT”项,获取该页面的用户代理的信息,来完成这个工作. [winows/chrome] 输出结果: Mozilla/5.0 ...
- Noip2014 提高组 day1 T1· 生活大爆炸版石头剪刀布
生活大爆炸版 石头剪刀布 描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第 8 集中出现了一种石头剪刀布的升级版 ...
- bjui给出的一个标准应用的首页
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...
- NABCD分析
NABCD——今日事 N(Need):开创的成就系统可以在一定程度上督促用户坚持下来. A(Approach):做一个APP软件,是在android平台构建. B(Benefit):可以逐步改变用户的 ...
- java,android获取系统当前时间
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");Date curDate = ...