统计难题

Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
 
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.

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

Sample Input
   
   
banana band bee absolute acm ba b band abc
 

Sample Output
   
   
2 3 1 0
  1. #define MAX 26  //字符集的大小  
  2.   
  3. /* 
  4. 字典树的存储结构 
  5. */  
  6. typedef struct Node  
  7. {  
  8.     struct Node *next[MAX]; //每个节点下面可能有MAX个字符  
  9.     int count;      //以从根节点到当前节点的字符串为公共前缀的字符串数目  
  10. }TrieNode,*TrieTree;  

(插入、查找、销毁等)
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include"data_structure.h"  
  5.   
  6. /* 
  7. 创建一棵仅有根节点的字典树 
  8. */  
  9. TrieTree create_TrieTree()  
  10. {  
  11.     TrieTree pTree = (TrieTree)malloc(sizeof(TrieNode));  
  12.     pTree->count = 0;  
  13.     int i;  
  14.     for(i=0;i<MAX;i++)  
  15.         pTree->next[i] = NULL;  
  16.     return pTree;  
  17. }  
  18.   
  19. /* 
  20. 插入字符串str到字典树pTree中 
  21. 由于不可能改变根节点,因此这里不需要传入pTree的引用 
  22. */  
  23. void insert_TrieTree(TrieTree pTree,char *str)  
  24. {  
  25.     int i;  
  26.     TrieTree pCur = pTree;  //当前访问的节点,初始指向根节点  
  27.     int len = strlen(str);  
  28.     for(i=0;i<len;i++)  
  29.     {  
  30.         int id = str[i] - 'a';  //定位到字符应该在的位置  
  31.         if(!pCur->next[id])  
  32.         {   //如果该字符应该在的位置为空,则将字符插入到该位置  
  33.             int j;  
  34.             TrieNode *pNew = (TrieNode *)malloc(sizeof(TrieNode));  
  35.             if(!pNew)  
  36.             {  
  37.                 printf("pNew malloc fail\n");  
  38.                 exit(-1);  
  39.             }  
  40.             pNew->count = 1;  
  41.             for(j=0;j<MAX;j++)  
  42.                 pNew->next[j] = NULL;  
  43.             //指针后移,比较下一个字符  
  44.             pCur->next[id] = pNew;  
  45.             pCur = pCur->next[id];   
  46.         }  
  47.         else  
  48.         {   //如果该字符应该在的位置不空,则继续比较下一个字符  
  49.             pCur = pCur->next[id];  
  50.             pCur->count++;   //每插入一个字符,公共前缀数目就加1  
  51.         }  
  52.     }  
  53. }  
  54.   
  55. /* 
  56. 统计字典树pTree中以str为前缀的字符串的数目 
  57. */  
  58. int count_TrieTree(TrieTree pTree,char *str)  
  59. {  
  60.     int i;  
  61.     TrieTree pCur = pTree;  
  62.     int len = strlen(str);  
  63.     for(i=0;i<len;i++)  
  64.     {  
  65.         int id = str[i] - 'a';  
  66.         if(!pCur->next[id])  
  67.             return 0;  
  68.         else  
  69.             pCur = pCur->next[id];  
  70.     }  
  71.     return pCur->count;  
  72. }  
  73.   
  74. /* 
  75. 销毁字典树 
  76. */  
  77. void destroy_TrieTree(TrieTree pTree)  
  78. {  
  79.     int i;  
  80.     //递归释放每个节点的内存  
  81.     for(i=0;i<MAX;i++)  
  82.         if(pTree->next[i])  
  83.             destroy_TrieTree(pTree->next[i]);  
  84.     free(pTree);  
  85. }  

int main()
{
	char str[10];
	TrieTree pTree = create_TrieTree();
	
	printf("Please input all string:\n");
	while(gets(str) && str[0] != '\0')
		insert_TrieTree(pTree,str);

	printf("\nplease intput prefix string:\n");
	while(gets(str) && str[0] != '\0')
		printf("The num of strings started with %s is %d\n",str,count_TrieTree(pTree,str));

	destroy_TrieTree(pTree);
	return 0;
}







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值