HDU 2222 Keywords Search (AC自动机)
题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同
AC自动机:trie树上进行KMP。首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在这一位不匹配时转移到失配指针上。失配指针是转移到某个等于此位置最长后缀的位置,求法是bfs
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
const int NumSize=;
struct node
{
int next[NumSize],coun;
int fail;//fail指针
void init()
{
memset(next,,sizeof(next));
coun=fail=;
}
} ACFA[Max];
int tot;
void Init()
{
tot=;
ACFA[tot].init();
return;
}
char str[Max];
void Insert(int len)//添加
{
int now=,mpos;
for(int i=; i<len; ++i)
{
mpos=str[i]-'a';
if(!ACFA[now].next[mpos])
{
ACFA[now].next[mpos]=++tot;
ACFA[tot].init();
}
now=ACFA[now].next[mpos];
}
ACFA[now].coun++;
return;
}
int que[Max];//bfs构造fail指针
void GetFail()//构造fail指针
{
int top=,bot=;
int now,fail;
for(int i=;i<NumSize;++i)//入队
if(ACFA[].next[i])
que[top++]=ACFA[].next[i];
while(top!=bot)
{
now=que[bot++];
for(int i=;i<NumSize;++i)
{
if(ACFA[now].next[i])
{
que[top++]=ACFA[now].next[i];
fail=ACFA[now].fail;
while(fail&&!ACFA[fail].next[i])//寻找失配指针位置
fail=ACFA[fail].fail;
if(ACFA[fail].next[i])//找到
fail=ACFA[fail].next[i];
ACFA[ACFA[now].next[i]].fail=fail;
}
else//建立trie图
ACFA[now].next[i]=ACFA[ACFA[now].fail].next[i];
}
}
return;
}
int Search(int len)
{
int ans=;
int mpos,nowp,now=;
for(int i=;i<len;++i)
{
mpos=str[i]-'a';
while(now>&&!ACFA[now].next[mpos])//失配后
now=ACFA[now].fail;
if(ACFA[now].next[mpos])//找到
{
now=ACFA[now].next[mpos];
nowp=now;
while(nowp&&ACFA[nowp].coun!=-)//-1找过
{
ans+=ACFA[nowp].coun;
ACFA[nowp].coun=-;
nowp=ACFA[nowp].fail;
}
}
}
return ans;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
Init();
scanf("%d",&n);
for(int i=; i<n; ++i)
{
scanf("%s",str);
Insert(strlen(str));
}
GetFail();
scanf("%s",str);
printf("%d\n",Search(strlen(str)));
}
return ;
}
HDU 2222 Keywords Search (AC自动机)的更多相关文章
- hdu 2222 Keywords Search——AC自动机
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222 第一道AC自动机! T了无数边后终于知道原来它是把若干询问串建一个自动机,把模式串放在上面跑:而且只 ...
- hdu 2222 Keywords Search ac自动机入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...
- HDU 2222 Keywords Search(AC自动机模板题)
学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...
- HDU 2222 Keywords Search (AC自动机)
题意:就是求目标串中出现了几个模式串. 思路:用int型的end数组记录出现,AC自动机即可. #include<iostream> #include<cstdio> #inc ...
- hdu 2222 Keywords Search ac自动机模板
题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...
- HDU 2222 Keywords Search (AC自动机)(模板题)
<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...
- hdu 2222 Keywords Search - Aho-Corasick自动机
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...
- hdoj 2222 Keywords Search(AC自动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 思路分析:该问题为多模式匹配问题,使用AC自动机解决:需要注意的问题是如何统计该待查询的字符串包 ...
- hdu 2222 Keywords Search ac自己主动机
点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- HDU 2222 Keywords Search AC自己主动机入门题
单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...
随机推荐
- perform
public class ArgsTest { private List <Object> args; private ArgsTestCheckPoint checkPoint; pub ...
- nyoj1000_快速幂_费马小定理
又见斐波那契数列 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 斐波那契数列大家应该很熟悉了吧.下面给大家引入一种新的斐波那契数列:M斐波那契数列. M斐波那契数列 ...
- CentOS7 win7 u盘装双系统 修复系统
环境: ASUS MB VER K45VD 笔记本电脑一台( i5-3230M 处理器. SATA . Nvidia). Windows7 系统 在 win7 下安装 CentOS7 使用 Ultra ...
- mysql 删除重复数据保留只保留一条
SELECT * FROM (SELECT addTime FROM motorcade.car_msg_info GROUP BY addTime HAVING COUNT(addTime) > ...
- CocoaPods安装教程
Code4App 原创文章.转载请注明出处:http://code4app.com/article/cocoapods-install-usage CocoaPods是什么? 当你开发iOS应 用时, ...
- chrome shortcutkey
按下Shift并点击链接 – 在新窗口打开链接. Ctrl+ – 切换到最后一个标签. Ctrl+Shift+V – 将剪切板中的内容无格式粘贴(举个例子,将你从网页中复制的HTML格式内容粘贴为纯文 ...
- Mysql之取消主从复制
Mysql5.7 Mysql取消主从复制很简单.只需在其要终止同步的Server上[一般是Slave]执行下面语句即可: stop slave; reset slave; 如图: .
- 原始套接字SOCK_RAW
原始套接字SOCK_RAW 实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包 ...
- iOS 文档分享相关
在非系统预览情况下 指定文件打开系统分享菜单 NSString *savedPath = [NSHomeDirectory() stringByAppendingString:[NSString s ...
- JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)
1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...