hdu 1251:统计难题[【trie树】||【map】
统计难题
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
tire树指针实现:
1 #include <cstdio> 2 #include <malloc.h> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 char s[15]; 8 struct node{ 9 int cnt; 10 node *next[26]; //该节点的所有子节点 11 void init(){ //初始化该节点 12 cnt=0; 13 for(int i=0;i<26;i++) 14 next[i]=NULL; 15 } 16 }; 17 void insert(node *root,char *s){ 18 node *p =root ,*now; 19 for(int i=0;s[i];i++){ 20 int tmp=s[i]-'a'; 21 if(p->next[tmp]==NULL){ //如果该节点为空,则创建一个新的节点 22 p->next[tmp]=new node; 23 p=p->next[tmp]; 24 p->init(); 25 } 26 else p=p->next[tmp]; //如果该节点不空,则继续向下插入 27 p->cnt++; //以该节点结尾的前缀个数+1 28 } 29 } 30 int find(node *root,char *s){ 31 node *p=root; 32 for(int i=0;s[i];i++){ 33 int tmp=s[i]-'a'; 34 p=p->next[tmp]; 35 if(!p)return 0; //如果遇到不满足的节点,就直接结束 36 } 37 return p->cnt; 38 } 39 int main(){ 40 node *root=new node; 41 root->init(); 42 while(gets(s)&&strlen(s)) 43 insert(root,s); 44 while(gets(s)) 45 printf("%d\n",find(root,s)); 46 return 0; 47 }
trie树数组实现:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int N = 1e6+10; 7 int trie[N][26]; //trie[now][next]代表第一次遍历到该节点的序号 8 int num[N]={0},pos=0; 9 void Insert(char *str){ 10 int now=0; 11 for(int i=0;str[i];i++){ 12 int next=str[i]-'a'; 13 if(!trie[now][next])trie[now][next]=++pos; //如果没有遍历过该节点,就给该节点赋值(相当于给trie树创建一个节点) 14 now=trie[now][next]; 15 num[now]++; //该前缀的数量+1 16 } 17 } 18 int Search(char *str){ 19 int now=0; 20 for(int i=0;str[i];i++){ 21 int next=str[i]-'a'; 22 if(!trie[now][next])return 0; //只要一找到不符合的节点,就直接返回0 23 now=trie[now][next]; //当前节点继续向下匹配 24 } 25 return num[now]; 26 } 27 int main(){ 28 char str[15]; 29 while(gets(str)&&strlen(str)) 30 Insert(str); 31 while(gets(str)) 32 printf("%d\n",Search(str)); 33 return 0; 34 }
map做法
#include <cstdio> #include <string> #include <map> #include <iostream> #include <algorithm> using namespace std; int main() { string s, str[10000]; int cur = 0; map<string, int>mapp; while (getline(cin, s) && s[0] != '\0') //注意是用这个来判断空行,首先一定要用getline读入,其次是s[0]=='\0'时表示是空行 { string ss; for (int i = 1; i <=s.length(); i++) { ss = s.substr(0, i); //获得字符串s中从第0位开始的长度为i的字符串 mapp[ss]++; } } while (cin >> s) { printf("%d\n", mapp[s]); } return 0; }
2018-04-08
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。