您的位置:首页 > 其它

HDU1251 统计难题(字典树模板题--数组实现+指针实现)

2016-11-18 22:18 435 查看
统计难题

Time Limit: 2000MS Memory Limit: 65535KB 64bit IO Format: %I64d & %I64u
Submit Status

Description

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

Input

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

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

Output

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

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc


Sample Output

2
3
1
0


标准的字典树模板题,不过要注意的也有几个地方

1.对于空行的判断,需要用到函数gets;该函数的用法是:gets(str),str是一个字符串数组,当读到空行时,str为“”;由此即可判断。

2.对于value数组,其初始化要在要用的时候才能进行,不然,,,T

3.这个题目没有给出单词个数,如果用数组实现的话,需要注意至少要有1000005;

4.用指针实现的时候只能用C++提交,不然会内存溢出。。。

代码如下:

数组实现,用时62ms,内存40724

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
char str[10];
int ch[1000005][26];
int value[1000005];
int sz=0;
void init(){
sz=1;memset(ch[0],0,sizeof(ch[0]));
//T了N次之后终于发现memset(value)不能发在这里。。。也不知道为什么这样就会超时。
}

void insertstr(char *s){
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int d=s[i]-'a';
if(!ch[u][d]){
memset(ch[sz],0,sizeof(ch[sz]));
value[sz]=0;
ch[u][d]=sz++;
}
u=ch[u][d];
value[u]++;
}
}

int findstr(char *s)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int d=s[i]-'a';
if(ch[u][d])u=ch[u][d];
else return 0;
}
return value[u];
}

int main(){
init();
while(gets(str)&&str[0])
insertstr(str);
while(gets(str)){
cout<<findstr(str)<<endl;
}
return 0;}

指针实现:用时 124ms,内存45272
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
struct My
{
int ncount;
My *node[26];
My()
{
ncount=0;
for(int i=0; i<26; i++)node[i]=NULL;
}
};
My *root=new My;
My *cur,*newnode;

void insertstr(char *str)
{
cur=root;
int len=strlen(str);
for(int i=0; i<len; i++)
{
int d=str[i]-'a';
if(cur->node[d]==NULL)
{

newnode=new My;
cur->node[d]=newnode;
}
cur=cur->node[d];
cur->ncount++;
}
}

int findstr(char *str)
{
cur=root;
int len=strlen(str);
for(int i=0;i<len;i++)
{
int d=str[i]-'a';
if(cur->node[d]!=NULL)cur=cur->node[d];
else return 0;
}
return cur->ncount;
}
int main()
{
char str[20];
while(gets(str)&&str[0])
insertstr(str);
while(gets(str))
{
cout<<findstr(str)<<endl;
}
return 0;
}

貌似数组好用一点,假如知道范围的话。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  字典树 HDU