hihoCoder#1036 Trie图

原题地址

看了这篇博文,总算是把Trie图弄明白了

Runtime Error了无数次,一直不知道为什么,于是写了个脚本生成了一组大数据,发现果然段错误了。

调试了一下午,总算闹明白了,为什么呢?

1. 空间超大的变量不要放在函数里,会爆栈,应该弄成全局变量或者是从堆上动态分配。

2. 看清题目的数据范围,一开始我的MAX_NODE设的是1024。。。

代码:

 1 #include <iostream>
 2 #include <cstring>
 3
 4 using namespace std;
 5
 6 #define MAX_NODE 1000010
 7 #define SIGMA_SIZE 32
 8
 9 int q[MAX_NODE];
10
11 struct TrieGraph {
12   int f[MAX_NODE];
13   int g[MAX_NODE][SIGMA_SIZE];
14   int m[MAX_NODE];
15   int size;
16
17   void init() {
18     size = 1;
19     memset(f, 0, sizeof(f));
20     memset(g[0], 0, sizeof(g[0]));
21   }
22
23   int index(char c) {
24     return c - ‘a‘;
25   }
26
27   void insert(const char *s) {
28     int u = 0;
29     while (*s) {
30       int i = index(*s);
31       if (!g[u][i]) {
32         memset(g[size], 0, sizeof(g[size]));
33         m[size] = 0;
34         g[u][i] = size++;
35       }
36       u = g[u][i];
37       s++;
38     }
39     m[u] = 1;
40   }
41
42   void build() {
43     int qh = 0, qt = 0;
44     f[0] = 0;
45     for (int i = 0; i < 26; i++) {
46       int &p = g[0][i];
47       if (p) {
48         f[p] = 0;
49         q[qt++] = p;
50       }
51       else
52         p = 0;
53     }
54     while (qh < qt) {
55       int u = q[qh++];
56       for (int i = 0; i < 26; i++) {
57         int &v = g[u][i];
58         if (v) {
59           q[qt++] = v;
60           f[v] = g[f[u]][i];
61           m[u] |= m[f[u]];
62         }
63         else
64           v = g[f[u]][i];
65       }
66     }
67   }
68
69   bool find(const char *s) {
70     int u = 0;
71     while (*s) {
72       int i = index(*s);
73       while (u && !g[u][i])
74         u = f[u];
75       u = g[u][i];
76       if (m[u])
77         return true;
78       s++;
79     }
80     return false;
81   }
82 } tg;
83
84 int main() {
85   int N;
86   string s;
87
88   tg.init();
89   cin >> N;
90   for (int i = 0; i < N; i++) {
91     cin >> s;
92     tg.insert(s.c_str());
93   }
94   tg.build();
95   cin >> s;
96   cout << (tg.find(s.c_str()) ? "YES" : "NO") << endl;
97   return 0;
98 }
时间: 2024-10-07 18:40:46

hihoCoder#1036 Trie图的相关文章

hihoCoder #1036 : Trie图 (AC自动机)

#1036 : Trie图 时间限制:20000ms 单点时限:1000ms 内存限制:512MB 描述 前情回顾 上回说到,小Hi和小Ho接受到了河蟹先生伟大而光荣的任务:河蟹先生将要给与他们一篇从互联网上收集来的文章,和一本厚厚的河蟹词典,而他们要做的是判断这篇文章中是否存在那些属于河蟹词典中的词语. 当时,小Hi和小Ho的水平还是十分有限,他们只能够想到:"枚举每一个单词,然后枚举文章中可能的起始位置,然后进行匹配,看能否成功."这样非常朴素的想法,但是这样的算法时间复杂度是相当

hihocoder 1036 Trie图(AC自动机)

传送门 Description 上回说到,小Hi和小Ho接受到了河蟹先生伟大而光荣的任务:河蟹先生将要给与他们一篇从互联网上收集来的文章,和一本厚厚的河蟹词典,而他们要做的是判断这篇文章中是否存在那些属于河蟹词典中的词语. 当时,小Hi和小Ho的水平还是十分有限,他们只能够想到:“枚举每一个单词,然后枚举文章中可能的起始位置,然后进行匹配,看能否成功.”这样非常朴素的想法,但是这样的算法时间复杂度是相当高的,如果说词典的词语数量为N,每个词语长度为L,文章的长度为M,那么需要进行的计算次数是在N

【hihoCoder】1036 Trie图

题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中的单词words. 相关基础的理解 1. 与用KMP解决的问题的差别 KMP:输入原串S和一个模式串T,判断T是否出现在S中.通过对T计算next数组,避免原串S的回溯. 现在的问题:输入文本串text和多个单词words,判断words中是否有出现在text中.同样希望输入的text不用进行回溯.

hiho一下 第二周&amp;第四周:从Trie树到Trie图

hihocoder #1014 题目地址:http://hihocoder.com/problemset/problem/1014 hihocoder #1036 题目地址: http://hihocoder.com/problemset/problem/1036 trie图其实就是trie树+KMP #1014trie树 #include<stdio.h> #include <algorithm> #include <cstring> #include <str

Trie图 &amp; AC自动机初学(1)

题目来源于:Hihocoder 时间限制:20000ms 单点时限:1000ms 内存限制:512MB 描述 前情回顾 上回说到,小Hi和小Ho接受到了河蟹先生伟大而光荣的任务:河蟹先生将要给与他们一篇从互联网上收集来的文章,和一本厚厚的河蟹词典,而他们要做的是判断这篇文章中是否存在那些属于河蟹词典中的词语. 当时,小Hi和小Ho的水平还是十分有限,他们只能够想到:"枚举每一个单词,然后枚举文章中可能的起始位置,然后进行匹配,看能否成功."这样非常朴素的想法,但是这样的算法时间复杂度是

Trie 图

时间限制:20000ms 单点时限:1000ms 内存限制:512MB 描述 前情回顾 上回说到,小Hi和小Ho接受到了河蟹先生伟大而光荣的任务:河蟹先生将要给与他们一篇从互联网上收集来的文章,和一本厚厚的河蟹词典,而他们要做的是判断这篇文章中是否存在那些属于河蟹词典中的词语. 当时,小Hi和小Ho的水平还是十分有限,他们只能够想到:“枚举每一个单词,然后枚举文章中可能的起始位置,然后进行匹配,看能否成功.”这样非常朴素的想法,但是这样的算法时间复杂度是相当高的,如果说词典的词语数量为N,每个词

Trie图

DFA 确定性有限状态自动机 DFA确定性有限状态自动机是一种图结构的数据结构,可以由(Q, q0, A, Sigma, Delta)来描述,其中Q为状态集,q0为初始状态,A为终态集合,Sigma为字母表,Delta为转移函数.它表示从唯一一个起始状态q0开始,经过有限步的Delta转移,转移是根据字母表Sigma中的元素来进行,最终到达终态集合A中的某个状态的状态移动.  如图所示是一个终态集合为{"nano"}的DFA.     DFA只能有一个起点而可以有多个终点.每个节点都有

hdu2457 Trie图+dp

hdu2457 给定n个模式串, 和一个文本串 问如果修改最少的字符串使得文本串不包含模式串, 输出最少的次数,如果不能修改成功,则输出-1 dp[i][j] 表示长度为i的字符串, 到达状态j(Trie图中的结点)所需要修改的最少次数 那么dp[0->n][0->size] = INF ,  dp[0][root] = 0,  n代表字符串长度, size代表状态数 那么答案就是  min{dp[n][size]} 我们根据模式串所建的Trie图, 进行模拟构造不包含模式串的字符串 从第一个

[hiho 04]Trie图

题目描述 Trie 图就是在 Trie 树上建立 fail 指针,类似于KMP算法中的next数组的作用. 这个数据结构的作用是判断一个字符串中是否包含一组字符串中的任意一个. 结构体定义是这样的: typedef struct trie_node { trie_node *nodes[26]; trie_node *fail = NULL; bool word_end = false; trie_node() { for (int i = 0; i < 26; i++) { nodes[i]