Match:Keywords Search(AC自动机模板)(HDU 2222)

                

                  多模匹配

  题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串。

  经典AC自动机模板题,不多说。

  

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <functional>
  4 #include <string.h>
  5 #define MAX 26
  6
  7 using namespace std;
  8
  9 struct node
 10 {
 11     node *fail, *next[MAX];
 12     int count;
 13 }Mem_Pool[500001], *Trie_Queue[500001];
 14 static int Used_Node;
 15 static char pattern[10001], target[1000001];
 16
 17 struct node *Get_New_Node(void);
 18 void Insert(struct node*);
 19 void Build_AC_Automation(struct node* const);
 20 static int Query(struct node* const);
 21
 22 int main(void)
 23 {
 24     int case_sum, pattern_sum;
 25     scanf("%d", &case_sum);
 26
 27     while (case_sum--)
 28     {
 29         Used_Node = 0;
 30         node *root = Get_New_Node();//每一次都拿一个新的根
 31         scanf("%d", &pattern_sum);
 32         getchar();
 33         while (pattern_sum--)
 34             Insert(root);
 35         Build_AC_Automation(root);
 36         gets(target);
 37         printf("%d\n", Query(root));
 38     }
 39 }
 40
 41 struct node *Get_New_Node(void)
 42 {
 43     Mem_Pool[Used_Node].count = 0;
 44     Mem_Pool[Used_Node].fail = NULL;
 45     memset(Mem_Pool[Used_Node].next, 0, sizeof(struct node *)*MAX);
 46
 47     return &Mem_Pool[Used_Node++];
 48 }
 49
 50 void Insert(struct node *root)
 51 {
 52     gets(pattern);
 53
 54     node *p = root;
 55     int index;
 56     for (int i = 0; pattern[i] != ‘\0‘; i++)
 57     {
 58         index = pattern[i] - ‘a‘;
 59         if (p->next[index] == NULL)
 60             p->next[index] = Get_New_Node();
 61         p = p->next[index];
 62     }
 63     p->count++;//表示这个位置包含着一个字符,如果有多个则叠加就可以了。
 64 }
 65
 66 void Build_AC_Automation(struct node *const root)//自动机的构造例程,其实就是个BFS
 67 {
 68     root->fail = NULL;
 69     int head = 0, back = 0;
 70     node *out = NULL, *tmp = NULL;
 71     Trie_Queue[back++] = root;
 72
 73     while (head != back)
 74     {
 75         out = Trie_Queue[head++];
 76         for (int i = 0; i < MAX; i++)//枚举所有情况
 77             if (out->next[i] != NULL)
 78             {
 79                 if (out == root)
 80                     out->next[i]->fail = root;//如果out自己就是根,那么直接将其子节点的失败指针指向自己就好了
 81                 else
 82                 {
 83                     for (tmp = out->fail; tmp != NULL; tmp = tmp->fail)
 84                         if (tmp->next[i] != NULL)
 85                         {
 86                             out->next[i]->fail = tmp->next[i];
 87                             //如果还找到在其他地方找到和他一样的元素,那么我们就把失败指针指向这个元素
 88                             break;
 89                         }
 90                     if (tmp == NULL)
 91                         out->next[i]->fail = root;
 92                 }
 93                 Trie_Queue[back++] = out->next[i];
 94             }
 95     }
 96 }
 97
 98 static int Query(struct node *const root)
 99 {
100     int ans = 0;
101     node *tmp = root, *other = NULL;
102     //tmp是跟着目标串的移动而移动的,other指针则表示在tire树的其他位置看还能不能匹配到其他字串
103     for (int i = 0; target[i] != ‘\0‘; i++)
104     {
105         int index = target[i] - ‘a‘;
106         while (tmp->next[index] == NULL && tmp != root)
107             tmp = tmp->fail;//沿着失败指针一直走
108         tmp = tmp->next[index];
109         tmp = (tmp == NULL) ? root : tmp;//检查如果是已经是root了,直接跳出来就好了
110         for (other = tmp; other != root && other->count != -1; other = other->fail)
111         {
112             ans += other->count;
113             other->count = -1;//标记一下,不要重复扫描
114         }
115     }
116     return ans;
117 }

  

时间: 2024-10-19 21:26:47

Match:Keywords Search(AC自动机模板)(HDU 2222)的相关文章

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

原题大意:原题链接 先给定T个单词,然后给定一个字符串,查询该字符串中包含多少个给定的单词 解题思路:AC自动机模板题 参考链接:哔哩哔哩算法讲堂 WA版本 注意:因为输入的单词可能有重复,那么Insert()函数中p->id=id;语句中p->id会被覆盖,在Query()函数中会一次性全部被清零,导致不能查询重复单词,以至于结果res错误. #include<queue> #include<cstdio> #include<cstring> using

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

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 67950    Accepted Submission(s): 22882 Problem Description In the modern time, Search engine came into the life of everybody lik

HDU 2222 Keywords Search AC自动机模板

题目链接: hdu2222 代码: #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<queue> using namespace std; struct node { int sum; node* fail; node* next[26]; node() { sum=0; fail=NULL; for(int i=0; i<26;

HDU 2222 Keyword Search AC自动机模板

#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #include <ctime> #include <io

HDU 2222 Keywords Search AC自动机入门题

单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自动机的基础: 1 Trie, 以这个数据结构为基础的,不过增加一个fail指针和构造fail的函数 2 KMP,不是直接运用KMP,而是需要KMP的思想,KMP思想都没有的话,理解这个算法会更加吃力的. 注意本题的单词会有重复出现的,一个单词只能统计一次. 搜索了一下网上的题解,发现好多代码都是一大抄的啊,⊙﹏⊙b汗. 本博客的乃是原创代码,代码风格也是差不多固定的,转载请注明出处:http://blog.c

[hdu2222] [AC自动机模板] Keywords Search [AC自动机]

AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <ctime> 7 #include <cstdlib> 8 #include <queue>

HDU 2222 Keywords Search (AC自动机入门 模板)

AC自动机入门 Aho-Corasick automaton,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.学习AC自动机之前得先有Trie树和KMP模式匹配算法的基础. AC自动机算法分为3步:1.构造一棵tire树  2.构造失败指针  3.进行模式匹配 AC自动机的优化:Trie图 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other

hdu 2222 Keywords Search(ac自动机入门题)

1 /************************************************************ 2 题目: Keywords Search(hdu 2222) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 4 算法: ac自动机 5 算法思想: 多个字符串匹配,也就是相当于多个kmp 6 ***********************************************************

HDU 2222 Keywords Search AC自动机

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 67122    Accepted Submission(s): 22584 Problem Description In the modern time, Search engine came into the life of everybody lik