|
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others) Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
Output 对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input banana band bee absolute acm ba b band abc
Sample Output 2 3 1 0
|
这道题用的是字典树解决,刚开始,对于字典树不熟悉的可以学着看看字典树模板再做题
代码:
#include<stdio.h>
#include<string.h>
#define max 26
char str [max] ;
struct Trie
{
int count;//遍历次数
Trie *elem[max] ;
Trie()
{
count = 0 ;
for(int i = 0 ; i < max ; i++)
elem[i] = NULL ;//对于每个节点下的元素赋初值为空
}//这里是利用的构造函数,并且初始化函数
};
Trie root;//建一个根节点
/*这里是建树*/
void Built_Trie()
{
Trie *p ;//用此指针来指向节点
p = &root ;//开始指针被赋予根节点的地址
int len = strlen(str);
for(int i = 0 ; i < len ; i++)
{
int a = str[i] - 'a' ;
if(p -> elem[a] == '\0')//当指针指向元素时,这个元素所占空间为空
{
Trie *q = new Trie ;//则新开一个空间
q -> count++ ;
p -> elem[a] = q ;
p = p -> elem[a] ;
}
else
{
p = p -> elem[a];
p -> count++;
}
}
}
/*这里是查找*/
void Find_Trie()
{
Trie *p ;
p = &root ;
int len = strlen(str) ;
int num = 0 ;//记录个字符串的次数
int flag = 0 ;
for(int i = 0 ;i < len ; i++)
{
int a = str[i] - 'a' ;
if(p -> elem[a] != '\0')
{
p = p -> elem[a] ;
num = p ->count ;
}
else
{
flag = 1 ;
break;
}
}
if(!flag)
{
printf("%d\n", num);
}
else
puts("0");
}
int main()
{
while(gets(str),strcmp(str,"\0"))
Built_Trie();
while(gets(str))
Find_Trie();
return 0 ;
}