字典树

本文介绍了一种利用前缀树(Trie)解决特定统计问题的方法。针对一系列由小写字母组成的单词,通过构建前缀树高效地统计出以特定字符串作为前缀的单词数量。文章提供了完整的C语言实现代码,并通过示例展示了如何处理输入数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

统计难题

时间限制(普通/Java):1000MS/10000MS     运行内存限制:65536KByte
总提交: 126            测试通过: 33

描述

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

输入

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

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

 

输出

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

样例输入

 

banana
band
bee
absolute
acm

ba
b
band
abc

 

样例输出

 

2
3
1
0

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define KIND 26  //字母最多26个
int t=0;
typedef struct trie
{
  int num;
  struct trie* next[KIND]; 
}TRIE;

void init_trie(TRIE* T)
{
  int i = 0;
  T->num = 0;
  for(; i<KIND; i++)
    T->next[i] = NULL; 
}

void add_trie(TRIE** T, char* word)
{
  int num = 0; 
  int i = 0;
  
  if(*T == NULL)
   {
     *T = (TRIE*)malloc(sizeof(TRIE));
     init_trie(*T); 
   }
   
   TRIE* location = *T; 
   while(word[i]!='/0')
   {
      num = word[i]-'a';
      if(location->next[num]!=NULL)
        (location->next[num]->num)++;
      else
       {
         TRIE* p = (TRIE*)malloc(sizeof(TRIE));
         init_trie(p); 
         location->next[num] = p; 
       }
       i++;
       location = location->next[num]; 
   } 
}

int find_trie(TRIE* T, char *word)
{
  int i = 0;
  int num;
  int ret = 1;
   t=0;
  TRIE* location = T;
  
  while(word[i]!='/0')
   {
     num = word[i]-'a';
      
      if(location->next[num]!=NULL)
       {
        i++;
    
        t=location->next[num]->num;
        
        location = location->next[num]; 
        
        }
      else
       {
         
         ret = 0;
         break; 
        } 
   } 
   
   return ret;
}
char word[100000][15];
int main()
{
  TRIE* T = NULL;
  int i = 0;
  int j;
  char tmp[15];
  for(i=0;;i++)
    {
        gets(word[i]);

        if(strlen(word[i])==0)
            break;
        
    }
  
  for(j=0;j<i;j++)
    add_trie(&T, word[j]);
    
  while(scanf("%s",tmp)!=EOF)
  if(find_trie( T, tmp))
  {
        printf("%d/n",t+1);
  }
  else
      printf("0/n");
  system("PAUSE");    
  return 0;
}

 

//////2009-1-1 写的 指针上的使用有区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值