一. 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251
二. 题目大意:给若干个单词,做为字典。再给出若干前缀,问每个前缀分别在字典的单词中出现多少次。
三. 思路:字典树模板题。所谓字典树,按本题来说,
1.首先有一个没有存信息的root,每个节点有26(字符集个数)个儿子。
2.插入操作:给一个单词,从第一个字符开始,依次从根节点开始,如果不存在此字符,新建一个新节点,否则,节点的计数域加1,循环一直到单词最后一个字符。
3.查询操作:给一个前缀,从第一个字符开始,依次从根节点开始,如果不存在,返回0,否则,查询完毕返回计数域中的数。
四.代码:
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N = 26;
const int INF = 0x3f3f3f3f;
struct node
{
int cnt;
node* next[MAX_N];
}heap[500000], root;
int top;
node *newNode()
{
return &heap[top++];
}
void addNode(char *str)
{
int len = strlen(str), i;
node *p = &root, *q;
for(i = 0; i < len; i++){
int key = str[i] - 'a';
if(p->next[key] == NULL){
q = newNode();
q->cnt = 1;
memset(q->next, 0, sizeof(q->next));
p->next[key] = q;
p = p->next[key];
}
else{
p = p->next[key];
p->cnt++;
}
}
}
int Find(char *str)
{
node *p = &root;
int i, key;
for(i = 0; str[i]; i++){
key = str[i]-'a';
if(p->next[key] == NULL)
return 0;
p = p->next[key];
}
return p->cnt;
}
int main()
{
//freopen("in.txt", "r", stdin);
char tmp[12];
while(gets(tmp) && tmp[0])
addNode(tmp);
while(~scanf("%s", tmp))
printf("%d\n", Find(tmp));
return 0;
}