HDU2222_Keywords Search _AC自动机模板题
来源:互联网 发布:java文件上传原理 编辑:程序博客网 时间:2024/06/02 05:39
题意
给出若干单词和一串字符,问这串字符中出现了给出单词中的几个。
思路
AC自动机模板题
AC自动机学习资料:
kuangbin大神的blog:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
包括AC代码中的第二种,也是直接从这里抄过来的
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2222
AC代码
这里代码有两版,第二个是照抄的kuangbin大神的,第二版稍微进行了一些改动,只是更靠近自己的风格,几乎可以说完全一样。
版本一
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int kind = 26;struct node{ node *fail; //fail指针 node *next[kind]; //子节点指针 int count; //当前节点代表的单词个数 node() { fail = NULL; count = 0; memset(next, NULL, sizeof next); }};node *q[500001]; //队列int head, tail; //队列的首尾指针char keyword[51]; //单词表char str[1000001]; //模式串void insert(char *str, node *root) //将单词插入字典树中{ node *p = root; int i = 0; while(str[i]) { int index = str[i] - 'a'; if(p->next[index] == NULL) p->next[index] = new node(); p = p->next[index]; i ++; } p->count ++;}void build_ac_automation(node *root){ head = tail = 0; q[head ++] = root; while(head != tail) { node *temp = q[tail ++]; node *p = NULL; for(int i= 0; i< 26; i++) //线序遍历子树 { if(temp->next[i] != NULL) { p = temp->fail; while(p != NULL) //沿着fail链找到一个与当前位置对应的位置,构造fail链 { if(p->next[i] != NULL) { temp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(p == NULL) temp->next[i]->fail = root; //加边失败,fail指针指向root q[head ++] = temp->next[i]; //子节点入队 } } }}int query(node *root){ int i = 0, cnt = 0, len = strlen(str); node *p = root; while(str[i]) //遍历模式串 { int index = str[i] - 'a'; while(p->next[index] == NULL && p != root) p = p->fail; //沿着fail链找一个能继续匹配的树枝,找到root也要停止 p = p->next[index]; if(p == NULL) p = root; //查找失败,p置为root node *temp = p; //沿着fail链检查是否有单词被构成 while(temp != root && temp->count != -1) //-1表示该单词已经被找过一次了 { cnt += temp->count; temp->count = -1; temp = temp->fail; } i ++; } return cnt;}int main(){ int n, t; scanf("%d", &t); while(t --) { node *root = new node(); scanf("%d", &n); getchar(); while(n --) { gets(keyword); insert(keyword, root); } build_ac_automation(root); scanf("%s", str); printf("%d\n", query(root)); } return 0;}
版本二
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int kind = 26;struct node{ node *fail; node *next[kind]; int count; node() { fail = NULL; count = 0; memset(next, NULL, sizeof next); }} *q[500001];char keyword[51];char str[1000001];int head, tail;void insert(char *str, node *root){ node *p = root; int i = 0, index; while(str[i]) { index = str[i] - 'a'; if(p->next[index] == NULL) p->next[index] = new node(); p = p->next[index]; i ++; } p->count ++;}void build_ac_automation(node *root){ int i; root->fail = NULL; q[head ++] = root; while(head != tail) { node *temp = q[tail ++]; node *p = NULL; for(int i= 0; i< 26; i++) { if(temp->next[i] != NULL) { if(temp == root) temp->next[i]->fail = root; else{ p = temp->fail; while(p != NULL) { if(p->next[i] != NULL) { temp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(p == NULL) temp->next[i]->fail = root; } q[head ++] = temp->next[i]; } } }}int query(node *root){ int i = 0, cnt = 0, index, len = strlen(str); node *p = root; while(str[i]) { index = str[i] - 'a'; while(p->next[index] == NULL && p != root) p = p->fail; p = p->next[index]; p = (p == NULL) ? root : p; node *temp = p; while(temp != root && temp->count != -1) { cnt += temp->count; temp->count = -1; temp = temp->fail; } i ++; } return cnt;}int main(){ int n, t; scanf("%d", &t); while(t --) { head = tail = 0; node *root = new node(); scanf("%d", &n); getchar(); while(n --) { gets(keyword); insert(keyword, root); } build_ac_automation(root); scanf("%s", str); printf("%d\n", query(root)); } return 0;}
阅读全文
0 0
- HDU2222_Keywords Search _AC自动机模板题
- 模板_AC自动机
- 模板_AC自动机
- 【字符串_AC自动机专辑】
- 踹图_AC自动机
- Vision_字符串_AC自动机
- HDU2222 Keywords Search AC自动机模板题
- HDOJ2222Keywords Search【AC自动机模板题】
- HDU2222 Keywords Search(AC自动机模板题)
- hdu2222Keywords Search AC自动机模板题
- hdu2222 Keywords Search(AC自动机模板题)
- Keywords Search(AC自动机模板题)
- HDU2222 Keywords Search 【AC自动机模板题】
- hdu2222Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search(AC自动机模板题)
- hdu 2222 Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search (AC自动机模板题)
- hdu 2222 Keywords Search(AC自动机模板题)
- mysql-5.7.12-winx64安装的时候无法启动服务问题
- 双链表的创建、删除、插入及打印(数据结构)
- JAVA中的反射机制
- 如何将BroadcastReceiver中的数据传递给activity?
- Spring简介
- HDU2222_Keywords Search _AC自动机模板题
- Android 实现自定义闹钟
- 系统时钟SYSCLK、HSE、HSI的讲解之《晶振与震荡电路的介绍》
- 原生js实现自定义事件
- 排序算法总结
- Timeline时间轴
- 104. Maximum Depth of Binary Tree
- 游戏开发中的人工智能(十):模糊逻辑
- 图像特征提取优秀的文章帖子