#1014 : Trie树

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?

身经百战的小Ho答道:“怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有单词,检查你给我的字符串是不是这个单词的前缀不就是了?

小Hi笑道:“你啊,还是太年轻了!~假设这本词典里有10万个单词,我询问你一万次,你得要算到哪年哪月去?”

小Ho低头算了一算,看着那一堆堆的0,顿时感觉自己这辈子都要花在上面了...

小Hi看着小Ho的囧样,也是继续笑道:“让我来提高一下你的知识水平吧~你知道树这样一种数据结构么?”

小Ho想了想,说道:“知道~它是一种基础的数据结构,就像这里说的一样!”

小Hi满意的点了点头,说道:“那你知道我怎么样用一棵树来表示整个词典么?”

小Ho摇摇头表示自己不清楚。

小Hi于是在纸上画了一会,递给小Ho,道:“你看这棵树和这个词典有什么关系?”

小Ho盯着手里的纸想了一会道:“我知道了!对于从树的根节点走到每一个黑色节点所经过的路径,如果将路径上的字母都连起来的话,就都对应着词典中的一个单词呢!

小Hi说道:“那你知道如何根据一个词典构建这样一棵树么?”

“不造!”

“想你也不知道,我来告诉你吧~”小Hi摆出一副老师的样子,说道:“你先这么想,如果我已经有了这样的一个词典和对应的一棵树,我要添加一个新的单词apart,我应该怎么做?”

“让我想想……”小Ho又开始苦思冥想:“首先我要先看看已经能走到哪一步了对吧?比如我从1号节点走"a"这一条边就可以走到2号节点,然后从2号节点走"p"这一条边可以走到3号节点,然后……就没路可走了!这时候我就需要添加一条从3号节点出发且标记为"p"的边才可以接着往下走……最后就是这样了!然后我把最后到达的这个结点标记为黑色就可以了。”

小Hi说道:“真聪明~那你不妨再算算如果是一个有10W个单词的词典,每个单词的长度不超过10的话,这棵树会有多大?”

小Ho于是掏出笔来,一边画一遍念叨:“假设我已经将前三个单词构成了这样一棵树,那么我要添加一个新的单词的时候,最坏情况是这个单词和之前的三个单词都没有公共前缀,那么这个新的单词的长度如果是5的话,我就至少要添加5个结点到树中才能够继续表示这个词典!”

“而如果每次都是最坏情况的话,这棵树最多也就100W个结点这么大!更何况最坏情况是不可能次次都发生的!毕竟字母表也才26个字母呢!”小Ho继续说道。

“嗯~这样我们是不是就可以用(单词个数*单词长度)个结点来表示一个词典了呢?小Hi问道。

“是的呢!”小Ho道:“但是这样一棵树又有什么用呢?”

“可别小看了它,它就是传说中的Trie树哦~至于他有什么用,一会你就知道了!”小Hi笑嘻嘻的回答道。

“你看,我们现在得到了这样一棵树,那么你看,如果我给你一个字符串ap,你要怎么找到所有以ap开头的单词呢?”小Hi又开始考校小Ho。

“唔...一个个遍历所有的单词?”小Ho还是不忘自己最开始提出来的算法。

“笨!这棵树难道就白构建了!”小Hi教训完小Ho,继续道:“看好了!”

小Hi在树上用绿色标出了一个节点,递给小Ho。

“这个结点……是从根节点先走"a"然后走"p"到达的结点呢!哦~~我知道了,以这个结点为根的子树里所有标记结点都是以"ap"为前缀的单词呢!而且所有以"ap"为前缀的单词都在以这个节点为根的子树里~”小Ho惊喜道。

“是的呢~那你对怎么解决我的问题有想法了么?”小Hi追问道。

“唔...那就是每次拿到你的字符串之后,我在树上找到其对应的那个结点,然后统计这个节点中有多少个标记节点?”小Ho不是很确定的答道:“但是这样...似乎在最坏情况,也就是你每次给个字符串都很短的时候,我还是要扫描这棵树的很大一部分呢?也就是说虽然平均时间复杂度降低了,但是最坏情况时间复杂度还是很高的样子!”

小Hi笑嘻嘻道:”没想到你自己看出来了呢~我还以为又要教训你了!~那你有什么好的解决方法么?”

“没呢!小Hi你就别卖关子了,赶紧告诉我吧!”被折磨的够呛的小Ho开始求饶。

“好吧!就帮你这一回~”

“小Ho你有没有想过这样一个问题?不妨称以T为根的子树中标记节点的个数为L[T],既然我要统计某个L[T1],,而这个结点是不确定的,我有没有办法一次性把所有结点的L[T]求出来呢?”小Hi整理了下思绪,问道。

“似乎是有的,老师以前说过,递归什么的。。”小Ho答道。

“递归太复杂了!我们可以之后再说,你这么想,在你构建Trie树的时候,当你经过一个结点的时候,说明了什么?”小Hi撇了撇头,继续问道。

“我想想,经过一个结点……标记结点……说明了以这个结点为根的子树中将要多出来一个标记结点?”

“没错!那你有没有什么办法来记录这个改变呢?”

“我想想,我在最开始置所有L[T]=0,然后每次添加一个新的单词的时候,都将它经过的所有结点的L[T]全部+1,这样我构建完这棵Trie树的时候,我也就能够同时统计到所有L[T]了,对么?”小Ho开心道。

“那么现在!赶紧去用代码实现吧!”小Hi如是说道

输入

输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问。

在20%的数据中n, m<=10,词典的字母表大小<=2.

在60%的数据中n, m<=1000,词典的字母表大小<=5.

在100%的数据中n, m<=100000,词典的字母表大小<=26.

本题按通过的数据量排名哦~

输出

对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。

样例输入

5
babaab
babbbaaaa
abba
aaaaabaa
babaababb
5
babb
baabaaa
bab
bb
bbabbaab
样例输出
1
0
3
0
0
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
#define L 10+1
//每个单词的长度
using namespace std;struct T{int num;T* next[26];T(){num=0;int i;for(i=0;i<26;i++)next[i]=NULL;}
}t;
void In(char str[]){T* p=&t;for(int i=0;str[i];i++){int a=str[i]-'a';if(p->next[a]==NULL)p->next[a]=new T;p=p->next[a];p->num++;}
}
int find(char str[]){T* p=&t;for(int i=0;str[i];i++){int a=str[i]-'a';if(p->next[a]==NULL)return 0;p=p->next[a];}return p->num;
}
int main(){int n,m;char str[L];for(scanf("%d",&n);n--;)scanf("%s",str),In(str);for(scanf("%d",&m);m--;)scanf("%s",str),printf("%d\n",find(str));return 0;
}

hiho一下第二周 Hihocoder #1014 : Trie树相关推荐

  1. hiho #1014 : Trie树(模板)

    Trie树 [题目链接]Trie树 &题意: 输入 输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英 ...

  2. hiho一下 第四周 Hihocoder #1036 : Trie图

    #1036 : Trie图 时间限制:20000ms 单点时限:1000ms 内存限制:512MB 描述 前情回顾 上回说到,小Hi和小Ho接受到了河蟹先生伟大而光荣的任务:河蟹先生将要给与他们一篇从 ...

  3. hiho一下第一周 Hihocoder #1032 : 最长回文子串

    #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  4. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  5. hihocoder 1014

    http://hihocoder.com/problemset/problem/1014 构建一棵字典树,然后进行字符串匹配就可以了 这个题我本来是想用java做,但是做了后才发现有那么多的错误,ja ...

  6. HihoCoder——Trie树

    本文出自:http://blog.csdn.net/svitter 原题:http://hihocoder.com/contest/hiho2/problem/1 题解:使用Trie树..基础题目.一 ...

  7. [hiho 02]Trie树

    题目描述 Trie树概念相对简单. 如果是用于保存英文词典,时空效率都是不错的. 如果保存中文词典,对子节点的索引可能需要用一个哈希表来存. 在建树的过程中可以顺便统计特定前缀的单词数. 如果要求重复 ...

  8. hihocoder-#1014 : Trie树

    题目来自于:hihocoder http://hihocoder.com/problemset/problem/1014 时间限制: 10000ms 单点时限: 1000ms 内存限制: 256MB ...

  9. 【bzoj3261】最大异或和 可持久化Trie树

    题目描述 给定一个非负整数序列 {a},初始长度为 N.        有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...

最新文章

  1. linux java tar 卸载_linux下jdk的卸载与安装
  2. Docker,容器,虚拟机和红烧肉
  3. php 复选框全选和取消,基于JavaScript实现复选框的全选和取消全选
  4. 怎么把文件放到docker容器里
  5. 互联网晚报 | 3月6日 星期天 |​ iPhone 14系列前置镜头或将采用“感叹号”设计;中央援港应急医院项目开工...
  6. 一些Python的惯用法和小技巧:Pythonic
  7. 如何正确利用肢体语言表达自己
  8. MOS管(场效应管)工作原理,及反向导通应用
  9. 手机免费使用PDF编辑器一键支持PDF转Word,随时随地处理文档
  10. Redis在项目中的应用(点评)
  11. 《红楼梦》的方位观念
  12. Android studio 可视化图表制作
  13. 小程序开发API之获取系统信息wx.getSystemInfo()、wx.getSystemInfoSync()
  14. vb中imp是什么意思_oracle
  15. 大一C语言总结贴(持更) Part1 输出菱形
  16. 专升本英语——语法知识——高频语法——第七节 特殊句型(全倒装-半倒装-强调句型-感叹句型-祈使句)【学习笔记】
  17. Nginx解决惊群效应
  18. 菜鸟第一次挑战apk逆向,结果整得怀疑人生,终于知道android apk加密的重要性...
  19. R语言如何绘制变异系数曲线(24)
  20. 网站中的个性及风格设计

热门文章

  1. 阐明性问题生成 (Clarification Question Generation) 概览
  2. 北京 | 免费高效训练及OpenVINO™加速推理深度学习实战,送Intel神经计算棒二代...
  3. 那个双非本科,还想转算法岗的姑娘,最后怎么了?
  4. Nosql数据库的四大分类
  5. SpringBoot注解自动扫描-底层实现
  6. Spring-级联赋值
  7. jfinal出现sql injection violation, multi-statement not allow : select count(*) select a.name,
  8. Spring Security + WebSocket——@MessageMapping中Authentication为NULL解决方案之一
  9. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】——第五章——自编解析与答案
  10. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】——第一章——自编解析与答案