题意:给出若干个单词和一段文本,问有多少个单词出现在其中。如果两个单词是相同的,得算两个单词的贡献。

  分析:直接就是AC自动机的模板了。

  具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = + ; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'a'])
stateTable[now].nxt[c-'a'] = size++;
now = stateTable[now].nxt[c-'a'];
}
stateTable[now].cnt++;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} int Get(int u)
{
int res = ;
while(u)
{
res += stateTable[u].cnt;
stateTable[u].cnt = ; //这里可做拓展
/*
这里清空的原因如下:
例如单词是he,需要匹配的文本是hehe
那么,我们在匹配完第一个he以后,会再次匹配he,
如果不清空,那么he这个单词就又被匹配了一遍。
10
1
abcab
abcabcab
对上面这个数据,如果不注释掉上面的语句,答案是1.
否则,答案是2.
10
2
abcab
abcabcab
abcabcabcab
*/
u = stateTable[u].fail;
}
return res;
} int match(char *s)
{
int n = strlen(s);
int res = , now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(stateTable[now].nxt[c-'a']) now = stateTable[now].nxt[c-'a'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'a'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'a'];
}
if(stateTable[now].cnt) res += Get(now);
}
return res;
}
}aho; int T,n;
char s[MAX_N]; int main()
{
int T;scanf("%d",&T);
while(T--)
{
aho.init();
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s);
aho.insert(s);
}
aho.build();
scanf("%s",s);
printf("%d\n",aho.match(s));
}
}

  顺便注意上面注释中的拓展点。

————————————————————————————————————————————————

  发现上面的代码有问题(虽然能AC),正确代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = + ; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'a'])
stateTable[now].nxt[c-'a'] = size++;
now = stateTable[now].nxt[c-'a'];
}
stateTable[now].cnt++;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} int Get(int u)
{
int res = ;
while(u)
{
if(stateTable[u].cnt == -) break;
res += stateTable[u].cnt;
stateTable[u].cnt = -;
u = stateTable[u].fail;
}
return res;
} int match(char *s)
{
int n = strlen(s);
int res = , now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(stateTable[now].nxt[c-'a']) now = stateTable[now].nxt[c-'a'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'a'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'a'];
}
//if(stateTable[now].cnt)
res += Get(now);
}
return res;
}
}aho; int T,n;
char s[MAX_N]; int main()
{
int T;scanf("%d",&T);
while(T--)
{
aho.init();
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s);
aho.insert(s);
}
aho.build();
scanf("%s",s);
printf("%d\n",aho.match(s));
}
}

HDU 2222 Keywords Search(AC自动机入门)的更多相关文章

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

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

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

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

  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. hdu2222 KeyWords Search AC自动机入门题

    /** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...

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

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

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

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

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

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

随机推荐

  1. 《C与指针》第二章练习

    本章问题 1.Comments in C do not nest(嵌套).What would be the result of "commenting out" the code ...

  2. HighCharts使用心得

    HighCharts使用心得 前言: 之前很早的一个项目中使用过highcharts,感觉挺方便的,图表类型也比较丰富,而且还支持数据的下钻,但是如果投入商业使用的话还会有一些版权的问题,所以后来就使 ...

  3. 全景视频外包团队:技术分享Unity3D全景漫游

    作者:未知 1.建模中使用的图片.文件.文件夹等以及模型中物体.材质等的名称都不能使用中文或者特殊符号,可以使用英文字母.数字.下划线等 2.调整Max的单位为米 3.烘培光影的设置 4.模型的中的植 ...

  4. Windows下用C++删除磁盘分区信息

    做一个能对U盘重新分区的小工具,使用该方法删除U盘中原有的分区表. bool CCesDiskDll::DestroyDisk(unsigned char deviceNumber) { DWORD ...

  5. discuz论坛与其它网站登录注册整合

    discuz论坛与其它网站登录注册整合 本文以discuz 7.0.0 php版本的论坛与 .net 2.0的网站注册登录整合为类.没有采用uc_center或第三方插件.以另类的方式实现.此方法实现 ...

  6. 每天一个 Linux 命令(12):more命令

    more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会 ...

  7. NineOldAndroid开源库简单使用demo

    看到很多开源库都使用了这个动画框架,就自己试了一下,果然很强大.把测试代码贴上,方便以后使用 package com.test.animation; import android.animation. ...

  8. 整理: Android HAL

    这篇文章整理来自http://bbs.chinaunix.net/thread-3675980-1-1.html 在论坛中看到的Android HAL讨论,有个ID描述的比较清楚,摘录如下: temp ...

  9. 使用gson解析,生成Json

    包:gson-2.3.jarJson文本解析为Java对象:Java对象生成为Json文本 import com.google.gson.Gson; public class TestGson { c ...

  10. 使用 Fiddler2 进行接口测试的方法

    一 前言 部分业务需要进行接口测试,而接口测试的覆盖度稍有不全,可能就会造成包括启动崩溃在内的严重问题.目前本人所在的团队中业务大量使用了本地代码中直接 mock 数据进行测试,此种方法虽然可以测试到 ...