【HDOJ】2222 Keywords Search

AC自动机基础题。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <queue>
  6 using namespace std;
  7
  8 #define MAXL  1000005
  9 #define TRIEN 26
 10
 11 char des[MAXL], src[55];
 12
 13 typedef struct Trie {
 14     int n;
 15     Trie *fail;
 16     Trie *next[TRIEN];
 17     Trie () {
 18         n = 0;
 19         fail = NULL;
 20         memset(next, 0, sizeof(next));
 21     }
 22 } Trie;
 23
 24 Trie *root;
 25 int n;
 26
 27 void create(char str[]) {
 28     int i=0, id;
 29     Trie *p = root, *q;
 30
 31     while (str[i]) {
 32         id = str[i] - ‘a‘;
 33         ++i;
 34         if (p->next[id] == NULL) {
 35             q = new Trie();
 36             p->next[id] = q;
 37         }
 38         p = p->next[id];
 39     }
 40     p->n++;
 41 }
 42
 43 void build_fail() {
 44     int i;
 45     Trie *p, *q;
 46     queue<Trie *> que;
 47
 48     for (i=0; i<TRIEN; ++i) {
 49         if (root->next[i]) {
 50             root->next[i]->fail = root;
 51             que.push(root->next[i]);
 52         }
 53     }
 54
 55     while (!que.empty()) {
 56         p = que.front();
 57         que.pop();
 58         for (i=0; i<TRIEN; ++i) {
 59             if (p->next[i]) {
 60                 q = p->fail;
 61                 while (q != NULL) {
 62                     if (q->next[i]) {
 63                         p->next[i]->fail = q->next[i];
 64                         break;
 65                     }
 66                     q = q->fail;
 67                 }
 68                 if (q == NULL)
 69                     p->next[i]->fail = root;
 70                 que.push(p->next[i]);
 71             }
 72         }
 73     }
 74 }
 75
 76 void search() {
 77     int i = 0, id;
 78     Trie *p = root, *tmp;
 79
 80     n = 0;
 81
 82     while (des[i]) {
 83         id = des[i] - ‘a‘;
 84         ++i;
 85         while (p->next[id]==NULL && p!=root)
 86             p = p->fail;
 87         p = p->next[id];
 88         if (p == NULL)
 89             p = root;
 90         tmp = p;
 91         while (tmp != root) {
 92             n += tmp->n;
 93             tmp->n = 0;
 94             tmp = tmp->fail;
 95         }
 96     }
 97 }
 98
 99 void del(Trie *t) {
100     if (t == NULL)
101         return ;
102     for (int i=0; i<TRIEN; ++i)
103         del(t->next[i]);
104     free(t);
105 }
106
107 int main() {
108     int case_n;
109
110     scanf("%d", &case_n);
111     while (case_n--) {
112         scanf("%d", &n);
113         root = new Trie();
114         while (n--) {
115             scanf("%s", src);
116             create(src);
117         }
118         scanf("%s", des);
119         build_fail();
120         search();
121         printf("%d\n", n);
122         del(root);
123     }
124
125     return 0;
126 }

【HDOJ】2222 Keywords Search

时间: 2024-10-16 15:07:11

【HDOJ】2222 Keywords Search的相关文章

【HDU】2222 Keywords Search

[算法]AC自动机 [题解]本题注意题意是多少关键字能匹配而不是能匹配多少次,以及可能有重复单词. 询问时AC自动机与KMP最大的区别是因为建立了trie,所以对于目标串T与自动机串是否匹配只需要直接访问对应结点,而不用真的比较. 因此可以预处理出拥有对应节点的失配串,不用一次一次跑前跑去找一样的. 然后还有就是一个结点可能对应多个串,所以需要last使统计答案完整. AC自动机的细节标注在代码里了. #include<cstdio> #include<cstring> #incl

HDOJ 题目2222 Keywords Search(AC自动机)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 38611    Accepted Submission(s): 12437 Problem Description In the modern time, Search engine came into the life of everybody like

【HDOJ】2279 File Search Tool

显然适用字典树建树,串长和模式串都很小,所以直接递归搜索.同时,适用bk标记当前的查询次数(排除不同模式的多次查询成功,如*t*).需要主要的是,居然存在同名文件!!!. 1 /* 2279 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #inc

【HDOJ】1648 Keywords

PE的注意,如果没有满足条件的不输出空格.简单模拟,暴力解. 1 /* */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include &

【题解】HDU-2222 Keywords Search

题目链接:HDU-2222  或  Vjudge 简单说明: ac自动机的建立,其中插入过程借助了字典树,处理回溯数组(也有人称失败数组)过程是一个广搜运用了STL的队列(queue).ac自动机的过程还在写. 这是学习ac自动机的第一题,如果wa的话,那就要注意,字串结束标记是如何标记的了.它不能单单 记录,还要 计数.WA了好几次-- my codes: #include <algorithm> #include <iostream> #include <cstring&

【HDOJ】2896 病毒侵袭

AC自动机模板题. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define TRIEN 128 8 #define MAXN 505 9 10 typedef struct Trie { 11 int in; 12 Trie *fail; 13 Trie *next[TRIEN];

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]