题目链接: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;
}