HDU 2222 Kerwords Search

代码风格模仿自:USETC每周算法讲解,AC自动机,郭老师!

输入一个T,对于每一个T给你一个n,接下来输入P个模式串,然后给你一个L串,L中出现了多少P中的串。

这是一道比较基础的AC自动机问题,我只不过是为了不想用板子而直接写,因此写此博文。
将容易遗漏或者写错的地方进行了注释的标注,用于提示自己,也用于与大家进行分享。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;const int maxn = 1e6 + 10;
const int mtop = 5e5 + 10;struct Aho {struct state {// 带fail指针的Trieint nxt[26];int fail, cnt;}stateTable[mtop];int sz;queue<int> q;void init() {while (!q.empty()) q.pop();for (int i = 0; i < mtop; i++) {memset(stateTable[i].nxt, 0, sizeof stateTable[i].nxt);stateTable[i].fail = stateTable[i].cnt = 0;}sz = 1;}void insert(char *S) {int len = strlen(S);int now = 0;for (int i = 0; i < len; i++) {char c = S[i];if (!stateTable[now].nxt[c - 'a']) {stateTable[now].nxt[c - 'a'] = sz++;}now = stateTable[now].nxt[c - 'a'];//stateTable[now].cnt++;}stateTable[now].cnt++;}void build() {stateTable[0].fail = -1;q.push(0);while (!q.empty()) {int u = q.front();q.pop();for (int i = 0; i < 26; i++) {if (stateTable[u].nxt[i]) {if (u == 0) {stateTable[stateTable[u].nxt[i]].fail = 0;}else {int v = stateTable[u].fail;while (v != -1) {if (stateTable[v].nxt[i]) {stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];break;// keep lengest?}v = stateTable[v].fail;}if (v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;}q.push(stateTable[u].nxt[i]);}}}}int Get(int u) {int res = 0;while (u) {res += stateTable[u].cnt;stateTable[u].cnt = 0;//work for Problem 2222u = stateTable[u].fail;}return res;}int match(char *S) {int len = strlen(S);int now = 0; int res = 0;for (int i = 0; i < len; i++) {int c = S[i];if (stateTable[now].nxt[c - 'a']) {now = stateTable[now].nxt[c - 'a'];}else {int p = stateTable[now].fail;while (p != -1 && stateTable[p].nxt[c-'a'] == 0) {p = stateTable[p].fail;}if (p == -1) {now = 0;}else {now = stateTable[p].nxt[c-'a'];}}if (stateTable[now].cnt) {// Sum of A of now->cnt;res += Get(now);}}return res;}
}aho;int main() {int T;scanf("%d", &T);char S[maxn];while (T--) {int n;scanf("%d", &n);aho.init();for (int i = 1; i <= n; i++) {scanf("%s", S);aho.insert(S);}aho.build();scanf("%s", S);int ans =  aho.match(S);cout << ans << endl;}return 0;
}

用于记录WA点的代码(容易出现问题的地方都通过注释进行了标记)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>using namespace std;const int maxn = 1e6 + 10;
const int maxtop = 5e5 + 10;struct Aho {struct state {int nxt[26];int cnt, fail;}stateTable[maxtop];int sz;queue<int> q;void init() {while (!q.empty()) q.pop();for (int i = 0; i < maxtop; i++) {memset(stateTable[i].nxt, 0, sizeof stateTable[i].nxt);stateTable[i].cnt = stateTable[i].fail = 0;}sz = 1;}void insert(char *S) {int len = strlen(S);int now = 0;for (int i = 0; i < len; i++) {char c = S[i];if (!stateTable[now].nxt[c - 'a'])stateTable[now].nxt[c - 'a'] = sz++;now = stateTable[now].nxt[c - 'a'];//lose}stateTable[now].cnt++;}void build() {stateTable[0].fail = -1;q.push(0);while (!q.empty()) {int u = q.front();q.pop();for (int i = 0; i < 26; i++) {if (stateTable[u].nxt[i]) {if (u == 0) {stateTable[stateTable[u].nxt[i]].fail = 0;}else {int v = stateTable[u].fail;while (v != -1) {if (stateTable[v].nxt[i]) {//wastateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];break;// lose lose lose !!!!!}v = stateTable[v].fail;}if (v == -1) {stateTable[stateTable[u].nxt[i]].fail = 0;}/*else {stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];}*///wa}q.push(stateTable[u].nxt[i]);}}}}int Get(int u) {int res = 0;while (u) {res += stateTable[u].cnt;stateTable[u].cnt = 0;u = stateTable[u].fail;}return res;}int match(char * S) {int now = 0;int res = 0;int len = strlen(S);for (int i = 0; i < len; 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 != -1 && stateTable[p].nxt[c - 'a'] == 0) {//wap = stateTable[p].fail;}if (p == -1) {now = 0;}else {now = stateTable[p].nxt[c - 'a'];//wa}}if (stateTable[now].cnt) {res += Get(now);}}return res;}}aho;int main() {int T;scanf("%d", &T);char S[maxn];while (T--) {int n;scanf("%d", &n);aho.init();for (int i = 1; i <= n; i++) {scanf("%s", S);aho.insert(S);}aho.build();scanf("%s", S);int ans = aho.match(S);cout << ans << endl;}return 0;
}

HDU 2222 Keywords Search【ACAM】相关推荐

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

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

  2. 【AC自动机】HDU 2222 Keywords Search 裸题

    题意:给出的n个单词,出现在T中的个数. #include <stdio.h> #include <string.h> #include <stdlib.h> #i ...

  3. hdu 2222:Keywords Search

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

  4. hdu 2222 Keywords Search(ac自动机)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:给你一系列子串,再给你一个主串问你主串一共有几个匹配子串 原来使用字典树写的但数据有点大T ...

  5. hdu 2222 Keywords Search AC自动机——多串匹配

    http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意: 给出n个单词,再给出一段包含m个字符的文章,求有多少个单词在文章里出现过. 思路: 才开开始以为简 ...

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

    一组数据: 1 3 sss sss sss sss ans:3 #include <cstdio> #include <cstdlib> #include <vector ...

  7. HDU - 2222 Keywords Search(AC自动机)

    题目链接:点击查看 题目大意:给出n个长度不超过50的模式串,再给出一个长度不超过1e6的主串,问模式串在主串中出现过多少次 题目分析:一开始我以为是求n次KMP,后来才知道这样做的时间复杂度是O(L ...

  8. HDU 2222 Keywords Search

    HDU_2222 今天开始学AC自动机了,这个就是我AC自动机的处女作了.这个题有个小trick就是单词列表中可能有重复的单词,但这些重复的单词应看做不同的,因此建字典树时做标记的时候,把原来的赋值为 ...

  9. AC自动机(HDU 2222: Keywords Search)

    题意: 输入n个单词,再输入一篇文章,判断有多少个单词在文章中出现过 http://blog.csdn.net/niushuai666/article/details/7002823 注释都在代码里 ...

最新文章

  1. java 继承先后顺序_Java中的继承关系的加载顺序
  2. linux shell let命令,shell编程中的let与(())
  3. linux c 得到指定进程内存占用
  4. mybaits中resultMap实现多对多查询映射
  5. android 8.0 调系统拍照_Android通知栏微技巧,8.0系统中通知栏的适配
  6. 操作 Wave 文件(5): 获取 Wave 文件的格式信息
  7. 测量学用C语言编程求子午线弧长,GPS数据解析 数据拆分 坐标转换 显示线路图源代码...
  8. 谁会成为中国互联网下一代英雄
  9. Hadoop入门集群环境搭建
  10. 数模(6):Leslie矩阵人口模型
  11. 服务器sel信息是什么意思,英特尔?服务器主板 — 如何解压和读取的服务器事件日志(SEL)...
  12. [导入]【沈殿霞张曼玉经典爆笑鬼片】《双肥临门》【国语DVD中字】
  13. Python爬虫 requests使用post请求发送文件
  14. php rsa 跨平台问题,为啥 rsa 这种算法扩展 php/python 不自带。而且跨平台也不是处理的很好...
  15. 10000条txt数据转为excel表格数据
  16. Windows 10 自带输入法微软拼音「简体」「繁体」切换快捷键
  17. 《50个教育法:我把三个儿子送入了斯坦福》书中的精髓:了解教育的本质,以言传身教、耐心引导的教育方式培养孩子成才。
  18. android8.1系统静默安装问题(无须手动点击)
  19. 为什么说施工是最蛋疼的工程行业
  20. 位是存储在计算机中的最小单位,在计算机中信息存储的最小单位是什么?

热门文章

  1. 3.使用单行函数——Oracle数据库学习日记
  2. shell脚本删除冒号空格_shell脚本如何删除指定字符串,文档如下:
  3. win10 使用bat创建python定时任务
  4. 双系统主系统重做后另外系统找回
  5. 蓝城兄弟完成私有化交割:从纳斯达克退市 作价6000万美元
  6. AE498 21组彩色烟雾路径生长特效效果视频素材ae模板
  7. Docker ENTRYPOINT 笔记
  8. Foxmail公司邮箱配置
  9. Json转换利器Gson之实例二-Gson注解和GsonBuilder
  10. 永磁同步电机无速度传感器控制(一)——滑模观测器(二)【滑模观测器设计过程】