hdu2846 Repository (字典树)

来源:互联网 发布:mac杀毒软件哪个好用 编辑:程序博客网 时间:2024/04/28 01:59

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846


题解:For each query, you just output the number of the merchandises, whose names contain the search string as their substrings.

        求输入的单词是字典里多少个单词的子串。


#include <stdio.h>  #include <string.h>  #define MAXN 500005  int tot;  typedef struct trie  {  int id;//最后一次经过此结点的商品ID int cnt;//当前单词出现的次数    struct trie *child[26];  }trie;  struct trie Trie[MAXN];  struct trie *root;  trie *newtrie()  {//静态分配空间  int i;  trie *ptr;  ptr=&Trie[tot++];  ptr->cnt=0;ptr->id=-1;//初始化每个节点的id为-1 for(i=0;i<26;++i)  ptr->child[i]=NULL;  return ptr;  }  void insert(char *str,int x)  {  int i,len,index;  trie *ptr=root;  len=strlen(str);  /*if(len==0)  return; */ for(i=0;i<len;++i)  {  index=str[i]-'a';  if(ptr->child[index]==NULL)ptr->child[index]=newtrie();//新增一节点  ptr=ptr->child[index];//更新节点  if(ptr->id!=x){//分解出的词的前缀与已经在之前分解的词的前缀相同(id==x),不能算作一种新的前缀  (ptr->cnt)++;ptr->id=x;}}  }  int query(char *str)  {  int i,len,index;  trie *ptr=root;  len=strlen(str);  if(len==0)  return 0;  for(i=0;i<len;++i)  {  index=str[i]-'a';  if(ptr->child[index]!=NULL)  ptr=ptr->child[index];  else  return 0;}  return ptr->cnt;}  int main()  {  char str[21];int n,m,i,j,len;tot=0;  root=newtrie();  scanf("%d",&n);for(i=0;i<n;++i){scanf("%s",str);len=strlen(str);for(j=0;j<len;++j)insert(str+j,i);}scanf("%d",&m);for(i=0;i<m;++i){scanf("%s",str);printf("%d\n",query(str));}return 0;  }