您的位置:首页 > 其它

hdoj 1251 统计难题(字典树)

2017-11-21 22:47 656 查看


统计难题(链接)

Input

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

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

 

Output

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

 

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

 

Sample Output

2
3
1
0

这道题可以用链表或者数组建树

链表的话用g++提交会MLE 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 26;   //26个字母
typedef struct node
{
int num;
struct node *son[maxn];
}Trie;

void insertWord(Trie *root,char word[])
{
Trie *p = root;
int i = 0;
char ch = word[i];  //用for循环写是一样的
while(ch != '\0')
{
if(p->son[ch-'a'] == NULL)
{
Trie *node = new Trie;
node->num=1;
for(int i = 0; i < maxn; i++)
{
node->son[i] = NULL;
}
p->son[ch-'a'] = node;
p = p->son[ch-'a'];
}
else
{
p->son[ch-'a']->num++;
p = p->son[ch-'a'];
}
ch = word[++i];
}
}

int findTrie(Trie *root,char s[])
{
Trie *p = root;
int i = 0;
char ch = s[i];
while(ch != '\0')
{
p = p->son[ch-'a'];
if(p == NULL)
return 0;
ch = s[++i];
}
return p->num;
}

int main()
{
char s[20];
Trie *root = new Trie;
for(int i=0;i<maxn;i++)
root->son[i] = NULL;
while(gets(s))
{
if(s[0]=='\0')
break;
insertWord(root,s);
}
memset(s,0,sizeof(s));
while(scanf("%s",s)!=EOF)
{
int ans=findTrie(root,s);
printf("%d\n",ans);
}
return 0;
}


用数组写的话一定要注意数组的大小太大的话也会MLE

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 400000;
int tree[maxn][27];
int val[maxn];
int flag;

void init()  //初始化
{
memset(tree,0,sizeof(tree));
memset(val,0,sizeof(val));
flag=1;  //标记  仔细理解一下
}

void build(char s[])
{
int len = strlen(s);
int u=0;
for(int i=0;i<len;i++)
{
int j=s[i]-'a';
if(tree[u][j]==0)
{
tree[u][j]=flag++;
}
u=tree[u][j];
val[u]++;   //以当前为前缀的字符串个数+1
}
}

int query(char s[])
{
int len = strlen(s);
int u=0;
for(int i=0;i<len;i++)
{
int j=s[i]-'a';
if(tree[u][j]==0)
return 0;
else
u=tree[u][j];
}
return val[u];
}

int main()
{
init();
char s[20];
while(gets(s))
{
if(strlen(s)==0)
break;
build(s);
}
while(gets(s))
{
if(strlen(s)==0)
break;
printf("%d\n",query(s));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: