hdu_1251统计难题(字典树Trie)

统计难题

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

Problem Description

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

Input

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

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

Output

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

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output

2 3 1 0

字典树的典型应用,主要要会写建树和查找树的过程。遍树的时候要用dfs 我发现用指针写树很好写,所以就用指针了,哈哈

下面是代码,字典树可以保存成模板,

这个题让我长知识的是对于输入输出的限制,还有c++和G++对内存管理的机智不太一样,这个题就是用G++交的时候回抄内存,用c++交就过了

然后输入的时候总结一下:

因为是scanf("%d",&tm) 是不会读入最后的回车的,而scanf("%c“,&ch)会读回车,所以在%d后面要是回车再读入%c的话要加getchar()

scanf("%s",Str)是不会读入回车的,它会自动忽略回车,且到回车停止。

所以如果输入需要读入回车的话需要用gets();

这个题还可以用set的方法过掉,因为字符串不超过10所以可以直接就把每个字符串的所有前缀放到set里然后再处理

字典树方法:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <malloc.h>
 4 #include <iostream>
 5 using namespace std;
 6 #define MAXN 26
 7 typedef struct Trie {
 8     int v;//根据需要变化
 9     Trie *next[MAXN];
10     //next是表示每层有多少种类的数,如果只是小写字母,则26即可,
11     //若改为大小写字母,则是52,若再加上数字,则是62了
12 } Trie;
13 Trie root;
14
15 void createTrie(char *str) {
16     int len = strlen(str);
17     Trie *p = &root, *q;
18     for(int i = 0; i < len; i++) {
19         int id = str[i]-‘a‘;
20         if(p->next[id] == NULL) {
21             q = (Trie *)malloc(sizeof(root));
22             q->v = 1;//初始v==1
23             for(int j = 0; j < MAXN; j++)
24                 q->next[j] = NULL;
25             p->next[id] = q;
26             p = p->next[id];
27         } else {
28             p->next[id]->v++;
29             p = p->next[id];
30         }
31     }
32     // p->v = -1;//若为结尾,则将v改成-1表示
33 }
34
35 int findTrie(char *str) {
36     int len = strlen(str);
37     Trie *p = &root;
38     for(int i = 0; i < len; i++) {
39         int id = str[i]-‘a‘;
40         p = p->next[id];
41         if(p == NULL) //若为空集,表示不存以此为前缀的串
42             return 0;
43         //  if(p->v == -1)   //字符集中已有串是此串的前缀
44         //      return -1;
45     }
46     return p->v;
47     //return -1;   //此串是字符集中某串的前缀
48 }
49 int dealTrie(Trie* T) {
50     //动态字典树,有时会超内存,这是就要记得释放空间了
51     if(T==NULL)
52         return 0;
53     for(int i = 0; i < MAXN; i++) {
54         if(T->next[i]!=NULL)
55             dealTrie(T->next[i]);
56     }
57     free(T);
58     return 0;
59 }
60 int main() {
61     char str[15];
62     for(int i = 0; i < MAXN; i++)
63         root.next[i] = NULL;
64     while(gets(str) && str[0]!=‘\0‘)
65         createTrie(str);
66     memset(str, 0, sizeof(str));
67     while(scanf("%s", str) != EOF) {
68         int ans = findTrie(str);
69         printf("%d\n", ans);
70     }
71     return 0;
72 }

set方法:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <map>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7
 8 int main()
 9 {
10   char str[17];
11   map<string, int> m;
12   while(gets(str))
13   {
14     int len = strlen(str);
15     if (!len)
16     {
17       break;
18     }
19     for(int i = len; i > 0; i--)
20     {
21       str[i] = ‘\0‘;
22       m[str]++;
23     }
24   }
25   while(gets(str))
26   {
27     cout<<m[str]<<endl;
28   }
29
30   return 0;
31 }
时间: 2024-11-18 22:43:24

hdu_1251统计难题(字典树Trie)的相关文章

hdu 1251 统计难题 字典树

// hdu 1251 统计难题 字典树 // // 题目大意: // // 有一系列的单词表,以空行结尾,之后会有一些字母串,找出以这些字符串 // 作为前缀的单词的个数 // // // 解题思路: // // 字典树 Trie,在插入字符串的时候每遇到一个节点,该节点的值++.查找的时候 // 字符串时,如果找到了,那么返回当前的val,否则返回0,因为没有以这个字符串 // 为前缀的单词. // // // 感悟: // // 这段时间想学学数据结构,就看了看刘老的大白书,感觉用数组挺巧

HDU 1251 统计难题(字典树)

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提

HDOJ/HDU 1251 统计难题(字典树啥的~Map水过)

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提

hdu 1251 统计难题 (字典树入门题)

1 /******************************************************* 2 题目: 统计难题 (hdu 1251) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=1251 4 算法: 字典树 5 提示: 这题压要用c++提交,G++会超内存 6 *******************************************************/ 7 #include<cstdio> 8

hdu 1251 统计难题 字典树水题

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Submission(s): 19627    Accepted Submission(s): 8612 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的

hdoj 1251 统计难题(字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 思路分析:该问题要求求出以某个字符串为前缀的单词数目,通过使用字典树,在字典树中添加count记录通过该结点的单词数目即可: 查找时找到前缀的最后一个单词的结点的count值即为所求: 代码如下: #include <cstdio> #include <cstring> #include <iostream> using namespace std; const in

HDU-1251统计难题 ,字典树

题意:问许多单词中,前缀是某个字符串的个数有多少个: 思路:  用字典树建立,每个节点带上num,记录每次insert是,经过这个点的次数, 每次询问,找到这个前缀对应的节点的num就ok 这道题,c++过,g++不行 ac代码: #include <iostream> #include <cstring> #include <algorithm> #include <string> #include <cstdio> using namespa

hdu1251统计难题(字典树)

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提

hdu1251 统计难题 字典树

Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提