字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
具体解释可看:链接传送门
数组代码模板:
const int MAXN = 1000005; //数组第一维大小,字符串的个数*最大长度
struct DicTree{
int cnt[MAXN]; //代表某个前缀的单词总个数
int tree[MAXN][26]; //注意修改这个儿子节点大小,全数字就是10,全小写字母就26
int tot;
/*void init(){
//特别说明多组数据才用init,否则一般不用,因为这种多个字符串输入一般都是一组数据
MEM(cnt,0);
MEM(tree,0);
tot=0;
}*/
void Insert(char *s){
int len = strlen(s);
int now=0;
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(!tree[now][id]){
tree[now][id] = ++tot;
}
now = tree[now][id];
cnt[now]++;
}
}
int Search(char *s){
int len=strlen(s);
int now=0;
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(!tree[now][id])
return 0;
now=tree[now][id];
}
return cnt[now];
}
}dictree;
指针代码模板:
struct DicTree{
const static int Size = 10; //注意修改这个儿子节点大小,全数字就是10,全小写字母就26
struct node{
int num; //有多少单词通过这个节点,即由根至该节点组成的字符串前缀出现的次数
node *Next[Size]; //儿子节点
node(){
for(int i=0;i<Size;i++)
Next[i] = NULL;
num=0;
}
};
node *root; //字典树根
DicTree(){
root = new node();
}
void Insert(char *s){
int id,len = strlen(s);
node *now = root;
for(int i=0;i<len;i++){
id = s[i] - '0';
if(now->Next[id]==NULL){ //说明当前路径没有了,需要新建
now->Next[id] = new node();
now->Next[id]->num++;
now = now->Next[id];
}
else{
now->Next[id]->num++;
now = now->Next[id];
}
}
}
int Search(char *s){
int id,len = strlen(s);
node *now = root;
for(int i=0;i<len;i++){
id = s[i]-'0';
now = now->Next[id];
if(now==NULL)
return 0;
}
return now->num;
}
void deal(node *now){ //多组数据一定要内存释放,否则会MLE
if(now==NULL)
return ;
for(int i=0;i<Size;i++){
if(now->Next[i] != NULL)
deal(now->Next[i]);
}
delete now;
}
};
DicTree dictree; //建立字典树