字典树的插入以及询问
建立字典树
struct node
{
int ch[26];//字典树编号为i时储存的字符在字典中与’a’的距离
int end;//表示每一个字典树的叶子节点编号
} tree[maxn]; //tree【i】表示字典树的当前节点编号
int k=0,len;//注意我们对节点的编号要定义全局变量 不然每建立一次新树 我们的编号并没按照顺序来统计
void tree_insert(char *str)
{
int len=strlen(str);
int root=0,c,i;
for(i=0; i<len; i++)
{
c=str[i]-'a';
if(!tree[root].ch[c])
tree[root].ch[c]=++k;
root=tree[root].ch[c];
}
tree[root].end=1;
}
字典树的访问
int tree_query(char *ss)
{
int qlen=strlen(ss);
int root=0,i,c;
for(i=0; i<qlen; i++)
{
c=ss[i]-'a';//注意:我们是用SS中的字符
if(!tree[root].ch[c])//如果找不到编号为ROOT出发的边 说明SS字符串在整个字典树当中并没有出现
return 0;
root=tree[root].ch[c];//直接访问已经存在的字符串的编号进行继续访问
}
return tree[root].sum;
}
求解字符串在字典树中出现的次数
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6;
struct node
{
int ch[26];//字典树编号为i的储存的字符在字典中与’a’的距离
int sum;//长度为编号i的字符串出现的次数
} tree[maxn]; //tree【i】表示字典树的当前节点编号
int k=0,len;
void tree_insert(char *str)
{
int len=strlen(str);
int root=0,c,i;
for(i=0; i<len; i++)
{
c=str[i]-'a';
if(!tree[root].ch[c])
tree[root].ch[c]=++k;
root=tree[root].ch[c];
tree[root].sum++;
}
}
int tree_query(char *ss)
{
int qlen=strlen(ss);
int root=0,i,c;
for(i=0; i<qlen; i++)
{
c=ss[i]-'a';
if(!tree[root].ch[c])
return 0;
root=tree[root].ch[c];
}
return tree[root].sum;
}
int main()
{
char str[30];
while (gets(str) && strlen(str))
{
tree_insert(str);
}
while (gets(str))
printf("%d\n", tree_query(str));
return 0;
}
0—1字典树(选择静态 动态 哪位路过大佬知道留言呗)
int tree[32 * maxn][2], val[32 * maxn], tot;//只是一个基本模板 后续更新/静态
void Insert(ll n)
{
int root = 0;
for (int i = 32; i >= 0; i--)
{
int id = (n >> i) & 1;
if (!tree[root][id])
tree[root][id] = ++tot;
root = tree[root][id];
}
val[root] = n;
}
ll get_ans(ll n)
{
int root = 0;
for (int i = 32; i >= 0; i--)
{
int id = (n >> i) & 1;
if (tree[root][id ^ 1])
root = tree[root][id ^ 1];
else
root = tree[root][id];
}
return val[root];
}
const int maxn=2e5;/动态模板
struct node
{
int ch[2];//字典树编号为i的储存边(二进制的0 OR 1)
LL val;//储存数
} tree[maxn]; //tree【i】表示字典树的当前节点编号
int k;
LL x[maxn];
void tree_insert(LL x)
{
int i,root=0;
for(i=32;i>=0;i--)
{
int c=(x>>i)&1;//把该数从高位开始的0 OR 1计算出来
if(!tree[root].ch[c])
tree[root].ch[c]=++k;
root=tree[root].ch[c];
}
tree[root].val=x;
}
LL tree_query(LL x)
{
int i,root=0;
for(i=32;i>=0;i--)
{
int c=(x>>i)&1;//采用贪心的策略 先从最高位开始找和1亦或的节点
if(tree[root].ch[c^1])
root=tree[root].ch[c^1];
else
root=tree[root].ch[c];
}
return tree[root].val;
}