HDU 1251统计难题

时间:2021-10-24 23:04:08

统计难题

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

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树。

trie树的节点

struct trie_node
{
int count;        //统计前缀的数目
trie_node * next[26];  //二十六个子节点
bool exict;        //是否为单词的结尾
}*root;

说到底trie树就是一颗26叉树,孩子有顺序,分别表示‘a'到’z'。

根节点不表示字符,也就是说字符是从根节点的孩子开始表示的。

每插入一个单词就判断下一个字母是否已经建立节点,建立了则进入,没有就插入节点。插入完整个单词后,更改exict为1;

查找时,从根节点开始判断下一个字母对应的节点是否存在,存在进入,否则判断有该前缀的单词个数为0。查找完整个前缀后,返回后缀最后一个字母对应的count值。

——————————————————————————————————————————————————————
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm> using namespace std;
struct trie_node
{
int count;
trie_node * next[];
bool exict;
}*root;
trie_node * create_tn()
{
trie_node * tp=new(trie_node);
tp->count=;
memset(tp->next,,sizeof(tp->next));
tp->exict=;
return tp;
}
void insert(char *word)
{
trie_node * p=root;
char *q=word;
while(*q)
{
int id=*q-'a';
if(p->next[id]==NULL)
p->next[id]=create_tn();
p=p->next[id];
++q;
p->count++;
}
p->exict=;
}
int search(char *word)
{
trie_node *p=root;
char *q=word;
while(*q)
{
int id=*q-'a';
p=p->next[id];
q++;
if(p==NULL)return ;
}
return p->count;
}
int main()
{
root=create_tn();
char s[];
bool bz=;
while(gets(s))
{
if(bz)printf("%d\n",search(s));
else
{
if(strlen(s)!=)
insert(s);
else bz=;
}
}
return ;
}