Trie数 --- 统计公共前缀
统计难题#
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 17386 Accepted Submission(s): 7515
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
【题目大意】
给你一些单词,然后再给你一些字符串,让你找这些字符串在单词中作为前缀出现的次数。
【题目分析】
Trie树的水题,当然这题使用map也可以过。
对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。
那么,对于一个单词,我只要顺着他从跟走到对应的节点,再看这个节点是否被标记为红色就可以知道它是否出现过了。把这个节点标记为红色,就相当于插入了这个单词。
这样一来我们询问和插入可以一起完成,所用时间仅仅为单词长度,在这一个样例,便是10。
们可以看到,trie树每一层的节点数是26^i级别的。所以为了节省空间。我们用动态链表,或者用数组来模拟动态。空间的花费,不会超过单词数×单词长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | //Memory Time // K MS #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<iomanip> #include<string> #include<climits> #include<cmath> #define MAX 1100 #define LL long long using namespace std; struct Node { int cnt; bool isWord; Node *next[30]; Node() { cnt=0; isWord= false ; for ( int i=0;i<30;i++) next[i]=NULL; } } *root=NULL; void Insert( char str[]) { if (!root) // 第一次的时候要为root申请内存 root= new Node; Node *location=root; int len= strlen (str); if (len==0) return ; for ( int i=0;i<len;i++) { int num=str[i]- 'a' ; if (location->next[num]!=0) // 表示该字符已经存在 { location=location->next[num]; // 直接跳到下一个字符 location->cnt++; // 下一个字符遍历次数+1 } else { location->next[num]= new Node; location=location->next[num]; location->cnt=1; } } // location->isWord=true; } int Search( char str[]) { Node *location=root; int len= strlen (str); if (len==0) return 0; for ( int i=0;i<len;i++) { int num=str[i]- 'a' ; if (location->next[num]!=NULL) location=location->next[num]; else //查找的字符串长度大于字典长度 return 0; } return location->cnt; } int main() { // freopen("cin.txt","r",stdin); // freopen("cout.txt","w",stdout); char str[30]; while ( gets (str), strcmp (str, "" )) Insert(str); int ans; while ( scanf ( "%s" ,str)!=EOF) cout<<Search(str)<<endl; return 0; } |
作者:北岛知寒
出处:https://www.cnblogs.com/crazyacking/p/3852021.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
标签:
Trie数 --- 统计公共前缀
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?