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

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. ffmpeg-20160728-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  2. ABAP 承运路单

    *&---------------------------------------------------------------------* *& Report  ZSDR010 ...

  3. 用原生DOM 遍历页面节点

    代码丢失,直接上图:

  4. vs2010 快捷键大全

    vs2010 快捷键大全 VS2010版快捷键 Ctrl+E,D ----格式化全部代码 Ctrl+E,F ----格式化选中的代码 CTRL + SHIFT + B生成解决方案 CTRL + F7 ...

  5. C++基础练习题(一): 查找最短单词

    /*<说明> 编程实现将字符串中最短的单词输出,在主函数中输入字符串,编写一个函数完成最短单词的查找 </说明>*/ #include<time.h> #inclu ...

  6. NEFU 506&&ZOJ 3353 Chess Board (四种构造的高斯消元)

    题目链接 题意:有四种翻转方式,问是否能使得所有棋子都变为0,求最小步数. 题解:依次构造枚举求出最小值即可. #include <iostream> #include <cstdi ...

  7. .Net SqlDbHelper

    using System.Configuration; using System.Data.SqlClient; using System.Data; namespace ExamDAL { clas ...

  8. September 24th 2016 Week 39th Saturday

    The worst solitude is to be destitute of sincere friendship. 最大的孤独莫过于没有真诚的友谊. I walk slowly, but I n ...

  9. 点击按钮对两个div的隐藏与显示进行切换

    HTML: <button type="button"  id="showHidden">点击切换div的隐藏与显示</button> ...

  10. 1.Windows安装PostgreSQL

    按照下面的步骤,Windows机器上安装PostgreSQL.请确保已开启第三方防病毒,同时安装. 挑选你想要的PostgreSQL的版本号,可以点击以下链接下载 EnterpriseDB Windo ...