Trie字典树应用HDU--1251

来源:互联网 发布:电路图制作软件下载 编辑:程序博客网 时间:2024/06/15 08:26

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>
04struct node
05{
06    int count ;
07    struct node *next[26];//定义26个分节点
08};
09struct node *root;
10struct 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}
22void 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}
41int 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}
57int 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}

 

 

0 0
原创粉丝点击