题目链接:https://vjudge.net/problem/HDU-1251
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana band bee absolute acm ba b band abc
Sample Output
2 3 1 0
字典树入门详解https://blog.csdn.net/Hackbuteer1/article/details/7964147
字典树入门题
这道题难在输入上~~~
这种是很懒的做法(耗时比较长 764ms)
#include<iostream>
#include<cstdio>
#include<string>
#include<map>
using namespace std;
map<string,int> mp;
int main(){
string ss;
while(getline(cin,ss)){
if(ss[0]=='\0') {
break;
}
int len=ss.size();
string s;
for(int i=0;i<len;i++){
s+=ss[i];
mp[s]++;
}
}
string s;
while(cin>>s){
cout<<mp[s]<<endl;
}
return 0;
}
刚学的字典树(124msG++MLE,C++AC)
输入用了个gets,不过现在gets好多已经不支持了,可以单个字符读入
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
struct Tnode{
int count;//单词前缀出现的次数
struct Tnode* next[26];//子节点
bool exist;//标记该结点处是否构成单词
};
typedef Tnode TN,*Trie;
Trie create(){ //创建结点
Trie node=(Trie)malloc(sizeof(TN));
node->count=0;
node->exist=false;
memset(node->next,0,sizeof(node->next));//初始化为空指针
return node;
}
void insert(Trie root,char *word){//插入
Trie node=root;
char *p=word;
int id;
while(*p){
int id=*p-'a';
if(node->next[id]==NULL){
node->next[id]=create();
}
node=node->next[id];
++p;
node->count+=1;//统计每个单词前缀出现的次数(也包括统计每个单词出现的次数)
}
node->exist=true; // 单词结束的地方标记此处可以构成一个单词
}
int search(Trie root,char *word){
Trie node=root;
char *p=word;
int id;
while(*p){
id=*p-'a';
node=node->next[id];
++p;
if(node==NULL)
return 0;
}
return node->count;
}
int main(){
Trie root=create();//初始化根节点
char s[20];
while(gets(s)){
if(s[0]=='\0') break;
insert(root,s);
}
while(~scanf("%s",s)){
printf("%d\n",search(root,s));
}
return 0;
}