题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同

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

  1. hdu 2222 Keywords Search——AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222 第一道AC自动机! T了无数边后终于知道原来它是把若干询问串建一个自动机,把模式串放在上面跑:而且只 ...

  2. hdu 2222 Keywords Search ac自动机入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...

  3. HDU 2222 Keywords Search(AC自动机模板题)

    学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...

  4. HDU 2222 Keywords Search (AC自动机)

    题意:就是求目标串中出现了几个模式串. 思路:用int型的end数组记录出现,AC自动机即可. #include<iostream> #include<cstdio> #inc ...

  5. hdu 2222 Keywords Search ac自动机模板

    题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...

  6. HDU 2222 Keywords Search (AC自动机)(模板题)

    <题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...

  7. hdu 2222 Keywords Search - Aho-Corasick自动机

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...

  8. hdoj 2222 Keywords Search(AC自动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 思路分析:该问题为多模式匹配问题,使用AC自动机解决:需要注意的问题是如何统计该待查询的字符串包 ...

  9. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  10. HDU 2222 Keywords Search AC自己主动机入门题

    单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...

随机推荐

  1. 算法手记 之 数据结构(并查集详解)(POJ1703)

    <ACM/ICPC算法训练教程>读书笔记-这一次补上并查集的部分.将对并查集的思想进行详细阐述,并附上本人AC掉POJ1703的Code. 在一些有N个元素的集合应用问题中,通常会将每个元 ...

  2. 【leetcode】Binary Tree Level Order Traversal I & II

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...

  3. IOS - 多态

    1. 多态性 多态性是个生物名词,用来表示生物体在生命周期中的不同形态,用在编程语言中则表示相同的方法名,但是却有不同的实现方式.或者说相同的名字,不同的类.我们来看一个书上的示例: #import  ...

  4. iOS 多线程及其他补充

      NSOperation NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类 NSInvocationOperation 如果直接执行NSInvocationOperatio ...

  5. 35. Search Insert Position

    题目: Given a sorted array and a target value, return the index if the target is found. If not, return ...

  6. [Android Pro] synchronized与static synchronized 的区别

    reference to :  http://www.cnblogs.com/shipengzhi/articles/2223100.html 1.synchronized与static synchr ...

  7. [Android Pro] Android保存图片到系统图库

    http://stormzhang.github.io/android/2014/07/24/android-save-image-to-gallery/ http://blog.csdn.net/x ...

  8. Linux内存性能指标、CPU性能指标

    内存性能指标 内存基础概念 先执行一下 top 命令,看结果中关于内存的相关部分 # top 其中的 VIRT.RES.SWAP 都是什么呢? 分别是下面的3个概念: 物理内存 Resident - ...

  9. ora-01400 无法将NULL插入 ID 解决方法

    问题描述:由于工作原因,把部分 字段改了,大体这样 StatementCallback; uncategorized SQLException for SQL [insert into test(sc ...

  10. Linux下Vi/Vim使用笔记

    启动和关闭vim vi 打开 Vi/Vim 打开 Vi/Vim 并加载文件 <file> vi <file> vim编辑器的三种模式:一般模式.编辑模式和命令行模式在一般模式中 ...