HDU1671——前缀树的一点感触

题目http://acm.hdu.edu.cn/showproblem.php?pid=1671

题目本身不难,一棵前缀树OK,但是前两次提交都没有成功。

第一次Memory Limit Exceeded:

前缀树是很费空间的数据结构,每个节点存放了字母(数字)个数个指针,正所谓用空间来换取时间。

我发现我忘记写析构函数了,所以测例多起来还不释放很容易超空间。

树形结构的析构也很有趣:

 1 ~Node()
 2 {
 3     for (int i = 0; i < 10; ++i)
 4     {
 5         if (children[i])
 6         {
 7             delete children[i];
 8             children[i] = nullptr;
 9         }
10     }
11 }

好了,第二次没成功,Time Limit Exceeded:

看起来这是一棵规规矩矩的前缀树,仔细找可以优化的地方,试探性地把

1 vector<Node *> children;
2 Node()
3 {
4     for (int i = 0; i < 10; ++i) children.push_back(nullptr);
5 }

改成了

1 vector<Node *> children = vector<Node *>(10, nullptr);
2 Node()
3 {
4     //for (int i = 0; i < 10; ++i) children.push_back(nullptr);
5 }

Accepted!显然构造的时候赋值比构造之后再赋值要快。。果然还是要尽可能的优化啊!

附代码:

 1 #include <string>
 2 #include <vector>
 3 #include <iostream>
 4
 5 using namespace std;
 6
 7 class Node
 8 {
 9 public:
10     bool is_phone = false;
11     vector<Node *> children = vector<Node *>(10, nullptr);
12     Node()
13     {}
14     ~Node()
15     {
16         for (int i = 0; i < 10; ++i)
17         {
18             if (children[i])
19             {
20                 delete children[i];
21                 children[i] = nullptr;
22             }
23         }
24     }
25     void insert(const string &_Phone)
26     {
27         Node *p = this;
28         for (int i = 0; i < _Phone.size(); ++i)
29         {
30             int curr = _Phone[i] - ‘0‘;
31             if (p->children[curr] == nullptr)
32             {
33                 p->children[curr] = new Node();
34             }
35             p = p->children[curr];
36         }
37         p->is_phone = true;
38     }
39     bool has_phone(const string &_Phone)
40     {
41         Node *p = this;
42         for (int i = 0; i < _Phone.size(); ++i)
43         {
44             int curr = _Phone[i] - ‘0‘;
45             if (!p->children[curr]) return false;
46             if (p->children[curr]->is_phone) return true;
47             p = p->children[curr];
48         }
49         return true;
50     }
51 };
52
53 typedef Node *Trie;
54
55 int main()
56 {
57     int t;
58     cin >> t;
59     while (t--)
60     {
61         Trie trie = new Node();
62         int n;
63         cin >> n;
64         string phone;
65         bool flag = true;
66         while (n--)
67         {
68             cin >> phone;
69             if (trie->has_phone(phone)) { flag = false; }
70             trie->insert(phone);
71         }
72         if (flag) cout << "YES" << endl;
73         else cout << "NO" << endl;
74         delete trie;
75     }
76     //system("pause");
77     return 0;
78 }
时间: 2025-01-15 17:43:12

HDU1671——前缀树的一点感触的相关文章

高级数据结构:优先队列、图、前缀树、分段树以及树状数组详解

优秀的算法往往取决于你采用哪种数据结构,除了常规数据结构,日常更多也会遇到高级的数据结构,实现要比那些常用的数据结构要复杂得多,这些高级的数据结构能够让你在处理一些复杂问题的过程中多拥有一把利器.同时,掌握好它们的性质以及所适用的场合,在分析问题的时候回归本质,很多题目都能迎刃而解了. 这篇文章将重点介绍几种高级的数据结构,它们是:优先队列.图.前缀树.分段树以及树状数组. 一.优先队列 1.优先队列的作用 优先队列最大的作用是能保证每次取出的元素都是队列中优先级别最高的,这个优先级别可以是自定

UVa 11732 &quot;strcmp()&quot; Anyone? (左儿子右兄弟前缀树Trie)

题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 字符串很多,又很长,如果按照题目的意思两两比较,肯定会TLE,所以要用前缀树(Trie)来解决,当然只是用简单的前缀树也会TLE的, 我们必须对其进行优化,看了

常用算法之Trie【字典树,前缀树】

Trie中文名又叫做字典树,前缀树等,因为其结构独有的特点,经常被用来统计,排序,和保存大量的字符串,经常见于搜索提示,输入法文字关联等,当输入一个值,可以自动搜索出可能的选择.当没有完全匹配的结果时,可以返回前缀最为相似的可能. 其实腾讯的面试题有一个:如何匹配出拼写单词的正确拼写.其实用匹配树非常合适. 基本性质: 1.根节点不含有字符,其余各节点有且只有一个字符. 2.根节点到某一节点中经过的节点存储的值连接起来就是对应的字符串. 3.每一个节点所有的子节点的值都不应该相同. 借用一下维基

·专题」 Trie(前缀树)

重新整理Trie的内容,还有一种叫做双链键树,不过到现在也不会写. Trie 可以称为字典树,也叫做前缀树,叫字典树很形象,叫前缀树可以很好的区分,因为还有一种树叫做后缀树 自己就不瞎总结了,写估计也写不好.关键是时间不允许. 参考两个blog A   B 先给一个比较标准的模板 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 #defin

9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第9章  查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.Scanf.c        相关测试数据

【暑假】[实用数据结构]前缀树 Trie

前缀树Trie Trie可理解为一个能够快速插入与查询的集合,无论是插入还是查询所需时间都为O(m) 模板如下: 1 const int maxnode = 1000+10; 2 const int sigma_size = 26; 3 4 struct Trie{ 5 int ch[maxnode][sigma_size]; 6 int val[maxnode]; 7 int sz; 8 9 void clear(){ sz=1; memset(ch[0],0,sizeof(ch[0]));

支持中文的基于词为基本粒度的前缀树(prefix trie)python实现

Trie树,也叫字典树.前缀树.可用于"predictive text"和"autocompletion".亦可用于统计词频(边插入Trie树边更新或加入词频). 在计算机科学中.trie,又称前缀树或字典树.是一种有序树,用于保存关联数组,当中的键一般是字符串.与二叉查找树不同.键不是直接保存在节点中,而是由节点在树中的位置决定.一个节点的全部子孙都有同样的前缀,也就是这个节点相应的字符串,而根节点相应空字符串. 普通情况下,不是全部的节点都有相应的值,仅仅有叶子

支持中文的基于词为基本粒度的前缀树(prefix trie)实现

Trie树,也叫字典树.前缀树.可用于”predictive text”和”autocompletion”,亦可用于统计词频(边插入Trie树边更新或添加词频). 在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串.与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定.一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串.一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相

【数据结构】前缀树/字典树/Trie

[前缀树] 用来保存一个映射(通常情况下 key 为字符串  value 为字符串所代表的信息) 例如:一个单词集合 words = {  apple, cat,  water  }   其中 key 为单词      value 代表该单词是否存在 words[ 'apple' ] = 存在     而     word[ ' abc' ] = 不存在 图示:一个保存了8个键的trie结构,"A", "to", "tea", "ted