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

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. 引入Fresco

    这里告诉你如何在项目中引入 Fresco. 使用 Android Studio 或者其他 Gradle 构建的项目 编辑 build.gradle 文件: 1 2 3 4 dependencies { ...

  2. tableView性能优化

    针对滑动时出现卡的现象 参考:http://blog.sina.cn/dpool/blog/s/blog_b638dc890101ep3x.html?plg_nld=1&plg_auth=1& ...

  3. objective-c字符串笔记

    字符串 //        字符串  分可变字符串和不可变字符串 //        不可变字符串的初始化方式 //        NSString *string = [[NSString allo ...

  4. maven编译时如何忽略单元测试

    共有两种解决办法 1.通过在命令行设置:-Dmaven.test.skip=true 如:mvn clean install tomcat:run -Dmaven.test.skip=true 2.通 ...

  5. C# 泛型约束

    一.泛型简介1.1泛型通过使用泛型,可以创建这样的类.接口和方法,它们以一种类型安全的工作方式操作各种数据.本质上,术语“泛型”指的是“参数化类型”(parameterized types).参数化类 ...

  6. XMPP框架下微信项目总结(3)获取点子名片信息(个人资料)更新电子名片

    思路:1 调用方法,添加点子名片模块(名片信息含电话,头像,单位个人信息)等 开启ps:APP发送请求到服务器openfire,服务器返回个人信息,app存储到数据库,app界面需要数据通过数据库获取 ...

  7. .net学习笔记----有序集合SortedList、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>

    无论是常用的List<T>.Hashtable还是ListDictionary<TKey,TValue>,在保存值的时候都是无序的,而今天要介绍的集合类SortedList和S ...

  8. Tensorflow 的Word2vec demo解析

    简单demo的代码路径在tensorflow\tensorflow\g3doc\tutorials\word2vec\word2vec_basic.py Sikp gram方式的model思路 htt ...

  9. Delphi强制类型转化和类型约定

    强制类型转换时一种技术,通过它能够使编译器把一种类型的变量当做另一种类型. 由于Pascal有定义新类型的功能,因此编译器在调用一个函数时候对形参和实参类型匹配的检查是非常严格的.因此为了能够通过编译 ...

  10. Java代码实现excel数据导入到Oracle

    1.首先需要两个jar包jxl.jar,ojdbc.jar(注意版本,版本不合适会报版本错误)2.代码: Java代码   import java.io.File; import java.io.Fi ...