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