问题描述
这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?”
数据结构
如上图所示就是一个trie树。
实现
树的构建
我们可以先计算出树的最大节点个数N,然后开辟长度为N个node的数组来存储树,设置一个变量trieNum 表示当前用了多少个节点,当要申请新节点时,将trieNum处的Node返回,并将trieNum++;
代码:
注意每个node 中的num 表示从根走到这点的字符串出现的次数。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
struct Node{
int num;
int next[26];
};
enum {maxn = 1000000+5};
struct Node trie[maxn];
int trieNum = 1;
void add(char *s)
{
int ptr = 0;
trie[0].num++;
for (int i=0; s[i]; i++)
{
if (trie[ptr].next[s[i]-'a'])
{
ptr = trie[ptr].next[s[i]-'a'];
}
else{// 申请新空间,并将指针指向下一级.
trie[ptr].next[s[i]-'a'] = trieNum;
ptr = trieNum;
trieNum++;
}
trie[ptr].num++;
}
}
int find(char *s)
{
int ptr=0;
int i;
for (i=0; s[i] && (ptr = trie[ptr].next[s[i]-'a']); i++);
if (!ptr)
return 0;
else
return trie[ptr].num;
}
#define OJ
int main()
{
#ifndef OJ
freopen("in.txt", "r", stdin);
#endif // OJ
memset(trie, 0, sizeof(struct Node)*maxn);
int n, m;
scanf("%d", &n);
char s[20];
while(n){
n--;
scanf("%s", s);
add(s);
}
scanf("%d", &m);
while(m){
m--;
scanf("%s", s);
printf("%d\n", find(s));
}
return 0;
}