AC automation 模板

  1 /*
  2 1.对n个字符串构造tire树                        insertWord(node *root, char *word);
  3 2.bfs构造fail指针                    makeFail(node *root);
  4 3.基于以上两点的查询                query(node *root, char *str);
  5 */
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <queue>
  9 using namespace std;
 10 const int N1 = 50 + 10;
 11 const int N2 = 1000000 + 10;
 12 char key[N1];
 13 char desc[N2];
 14 struct node
 15 {
 16     node *next[26];
 17     int cnt;
 18     node *fail;
 19     node(){for(int i=0; i<26; ++i) next[i] = NULL; fail = NULL; cnt = 0;}
 20 };
 21 void insertWord(node *root)//构造trie树
 22 {
 23     node *cur = root;
 24     int n = strlen(key);
 25     for(int i=0; i<n; ++i)
 26     {
 27         int index = key[i] - ‘a‘;
 28         if(cur->next[index] != NULL)
 29             cur = cur->next[index];
 30         else
 31         {
 32             cur->next[index] = new node();
 33             cur = cur->next[index];
 34         }
 35     }
 36     cur->cnt++;
 37 }
 38 void makeFail(node *root)//构造fail指针
 39 {
 40     queue<node*> q;
 41     q.push(root);
 42     node *cur;
 43     while(!q.empty())
 44     {
 45         cur = q.front();
 46         q.pop();
 47         for(int i=0; i<26; ++i)
 48         {
 49             if(cur->next[i] != NULL)
 50             {
 51                 if(cur == root)//与root相连的结点,即第二层的结点的fail指针都是root
 52                     cur->next[i]->fail = root;
 53                 else
 54                 {
 55                     node *tmp = cur;
 56                     while(tmp->fail != NULL)// why while?
 57                     {
 58                         if(tmp->fail->next[i] != NULL)
 59                         {
 60                             cur->next[i]->fail = tmp->fail->next[i];
 61                             break;
 62                         }
 63                         tmp = tmp->fail;
 64                     }
 65                     if(tmp->fail == NULL)
 66                         cur->next[i]->fail = root;
 67                 }
 68                 q.push(cur->next[i]);
 69             }
 70         }
 71     }
 72 }
 73 int query(node *root)//查询
 74 {
 75     node *cur = root;
 76     node *tmp = NULL;
 77     int i=0,cnt=0;
 78     while(desc[i])
 79     {
 80         int index = desc[i] - ‘a‘;
 81         while(cur!=root && cur->next[index] == NULL)
 82             cur = cur->fail;
 83         if(cur->next[index] != NULL)
 84         {
 85             cur = cur->next[index];
 86             tmp = cur;
 87             while(tmp != root && tmp->cnt!=0)
 88             {
 89                 cnt += tmp->cnt;
 90                 tmp->cnt = 0;
 91                 tmp = tmp->fail;
 92             }
 93         }
 94         i++;
 95     }
 96     return cnt;
 97 }
 98 int main()
 99 {
100     int t,n;
101     scanf("%d",&t);
102     while(t--)
103     {
104         node *root = new node();
105         scanf("%d",&n);
106         for(int i=0; i<n; ++i)
107         {
108             scanf("%s",key);
109             insertWord(root);
110         }
111         makeFail(root);
112         scanf("%s",desc);
113         int ans = query(root);
114         printf("%d\n",ans);
115     }
116     return 0;
117 }

时间: 2024-10-30 01:47:26

AC automation 模板的相关文章

LA 4670 出现次数最多的子串 (AC自动机模板题)

Dominating Patterns Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description The archaeologists are going to decipher a very mysterious ``language". Now, they know many language patterns; ea

hdu5384 AC自动机模板题,统计模式串在给定串中出现的个数

http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsoft, the series' name is compounded from the Japanese words for "bullet" (dangan) and "refutation&q

hdu2222(ac自动机模板)

先推荐两篇写的很好的ac自动机blog: http://blog.csdn.net/creatorx/article/details/71100840 http://blog.csdn.net/niushuai666/article/details/7002823 正题 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意: 给出 n 个模式串以及一个 主串, 问有多少个模式串在主串中出现过 思路: ac自动机模板题 代码: 1 #inc

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 {

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

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

[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(AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题思路: AC自动机模板题. 一开始使用LRJ的坑爹静态模板,不支持重复的模式串. 在做AC自动机+DP的时候,扒了zcwwzdjn大神的动态优化(失配指向root)写法,以及借鉴了网上的AC自动机模板, 搞出了这么一个支持重复串的模板. #include "cstdio" #include

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

NYOJ 1085 数单词 (AC自动机模板题)

数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 为了能够顺利通过英语四六级考试,现在大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中可以通过六级,可是没想到,成绩出来以后,居然没有通过.所以他不得不付出更多的时间来学习英语. 要想通过六级,最基本的要求就是词汇量.为了能够更快的记住一些陌生单词,LYH有时会找一些英语文章来读. 今天早上,LYH又找了一篇文章.读之前,他突然萌生出一个想法:文章中哪些单词出现的次数最多呢? 输入 第一行输入一个