Trie字典树应用HDU--1251

HDU–1251题 统计难题

这个题用到了字典树。  这个知识点是栋栋哥上个星期五讲的,其他几个人也都做过这方面的练习,我直到昨天下午才弄字典树的题。速度慢了不止一拍。这两天学校的网速基本就是老乌龟一个档次的,昨天更是神奇的连网页也打不开,所以这篇解题报告直到 现在才写。各位,原谅我的懒惰吧!

简单的写一下自己的思路和感悟。字典树其实是一种非常好用的统计方法,特别是当传统的排序、统计方法浪费了大量时间和内存的情况下。字典树,顾名思义,就是建立一个树,而分叉则是一些字母。我们建立一个节点,储存一个字母,然后再建立另外一个节点,储存另外一个 字母。用链表来链接。可能你会很晕乎,没事,一会我会单独写篇字典树的学习笔记,嘿嘿。

至于这个题,就是直白的字典树的应用,唯一需要注意的就是一些小的细节。我昨天花了2个多小时才弄出这个题目来。各种小错误,弄得很头大。其实就是因为自己没有熟练的掌握这个方法,写的很生硬。

原题地址:HDU 1251题(点击打开)

原题描述:

统计难题

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 8549 Accepted Submission(s): 3411

Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

Output
对于每个提问,给出以该字符串为前缀的单词的数量.

Sample Input
banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output
2
3
1
0

代码如下:(注意一下我写的注释)

01 #include<stdio.h>
02 #include<string.h>
03 #include<stdlib.h>
04 struct node
05 {
06     int count ;
07     struct node *next[26];//定义26个分节点
08 };
09 struct node *root;
10 struct node *build()//建立节点
11 {
12     struct node *p;
13     p=(struct node *)malloc(sizeof(struct node));
14     for(int i=0;i<26;i++)
15     {
16         p->next[i]=NULL;//令其指向0;
17     }
18         p->count=1;/*如果出现这个站点,那么它的次数肯定是大于等于1的。
19         但是我们刚开始建立不必考虑后续问题*/
20     return p;//返回新建立的节点
21 }
22 void save(char *s)//储存字母
23
24     int len=strlen (s);
25     if(len==0)return ;
26     struct node *p;
27     p=root;
28     for(int i=0;i<len;i++)
29         if(p->next[s[i]-'a']!=NULL)
30             /*如果这个节点之前就已经存在呃,我们只需要把统计次数加上1.*/
31         
32             p=p->next[s[i]-'a'];
33             p->count=p->count+1;
34         }
35         else//如果不存在的话,我们就建立一个新的节点
36         {
37             p->next[s[i]-'a']=build();
38             p=p->next[s[i]-'a'];
39         }
40 }
41 int seach (char *s)//这个函数来查询数据
42 {
43     struct node *p;
44     int len=strlen(s);
45     if(len==0)return 0;
46     p=root;//此处小心
47     for(int i=0;i<len ;i++)
48     {
49         if(p->next[s[i]-'a']!=NULL)//说明还有下个节点,继续查询
50             p=p->next[s[i]-'a'];
51         else
52             return 0;
53         /*如果没有指向下个节点,说明这个要查询的字符串根本不存在,直接返回0*/
54     }
55     return p->count;
56 }
57 int main()
58 {
59     char str[15];
60     int i,ans;
61     root=build();
62     while(gets(str)&&str[0]!='\0')
63         save(str);
64     while(~scanf("%s",str))
65     {
66         ans=seach(str);
67         printf("%d\n",ans);
68     }
69     return 0;
70 }

 

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/shixiaoguo90/article/details/23842355
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞