又称单词查找树,Trie树,前缀树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。
![Trie1](http://www.wutianqi.com/wp-content/uploads/2010/09/Trie1.jpg)
字典树与字典很相似,当你要查一个单词是不是在字典树中,首先看单词的第一个字母是不是在字典的第一层,如果不在,说明字典树里没有该单词,如果在就在该字母的孩子节点里找是不是有单词的第二个字母,没有说明没有该单词,有的话用同样的方法继续查找.字典树不仅可以用来储存字母,也可以储存数字等其它数据。
实战训练:
输入
输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问。
在20%的数据中n, m<=10,词典的字母表大小<=2.
在60%的数据中n, m<=1000,词典的字母表大小<=5.
在100%的数据中n, m<=100000,词典的字母表大小<=26.
本题按通过的数据量排名哦~
输出
对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。
5 babaab babbbaaaa abba aaaaabaa babaababb 5 babb baabaaa bab bb bbabbaab
1 0 3 0 0
代码:
#include <iostream>
#include <vector>
using namespace std;
struct Node {
char val;
int freq;
Node *next[26];
Node(int v, int f): val(v), freq(f) {
int i;
for (i=0; i<26; ++i) {
next[i] = NULL;
}
}
Node():freq(0) {
int i;
for (i=0; i<26; ++i) {
next[i] = NULL;
}
}
};
vector<int> Create(vector<string> &dict, Node *root, vector<string> &str) {
vector<int> res;
int i, len = dict.size(), j;
Node *node;
for (i=0; i<len; ++i) {
node = root;
for (j=0; j<dict[i].size(); ++j) {
if (node->next[dict[i][j]-'a'] == NULL) {
node->next[dict[i][j]-'a'] = new Node(dict[i][j], 1);
}
else {
node->next[dict[i][j]-'a']->freq++;
}
node = node->next[dict[i][j]-'a'];
}
}
for (i=0; i<str.size(); ++i) {
node = root;
for (j=0; j<str[i].size(); ++j) {
if (node->next[str[i][j]-'a'] == NULL) {
break;
}
else {
node = node->next[str[i][j]-'a'];
}
}
if (j == str[i].size()) {
res.push_back(node->freq);
}
else {
res.push_back(0);
}
}
return res;
}
int main() {
vector<string> dict;
vector<string> str;
vector<int> res;
int n,m;
while (cin >> n) {
dict.clear();
str.clear();
res.clear();
dict.resize(n);
int i;
for (i=0; i<n; ++i) {
cin >> dict[i];
}
cin >> m;
str.resize(m);
for (i=0; i<m; ++i) {
cin >> str[i];
}
Node *root = new Node(' ', 0);
res = Create(dict, root, str);
for (i=0; i<res.size(); ++i) {
cout << res[i] << endl;
}
}
return 0;
}