【数据结构】浅析字典树(Trie)

字典树是一种比较容易的数据结构,个人觉得理解起来比较简单,只要掌握几个基本要点就可以了

1.字典树有一个超级原点是0点

2.因为超级原点的存在,所以在查询的时候(比如说查前缀的数量),要加的不是当前节点的cnt[now],而是son[now][u]的cnt,这样就可以避免自己忘了在最后加上cnt[now]

3.插入的操作也是比较简单,注意的是把now循环到最后一点的时候再加cnt,也就是在for循环外侧进行懒惰标记,方便以后查找

4.字典树里的懒惰标记就是以当前节点为结尾的字符串有多少个

5.怎么开数组的大小呢,这是一个匪夷所思的问题,一般的话题目上会给出一个数据范围说是整体的字符串长度不超过N

6.查询的时候一层一层向下跳就行,就和lca暴力的思想是一样的,

7.字典树的复杂度还是很好的,一般是O(logn*m),其实是比map更加优化的数据结构,考到字符串的时候,可以用一下

8.字典树的转换思想,可以把一个数的每一位二进制,左补全0,对齐之后,从根节点开始建树

9.尤其注意的是,建立一个新节点的时候,如果idx是0开始的话,要++idx,不能把0号点覆盖掉

10.字典树和kmp是字符串的唯二算法,要考的话,必须要会哦~!!

下面给出模板代码

const int Maxn=2e6+5;
int n,m,idx;
int son[Maxn][28],cnt[Maxn];
char a[Maxn];
inline void insert_tree(char t[])
{
	int len=strlen(t),now=0;
	for(int i=0;i<len;i++)
	{
		int u=t[i]-'a';
		if(son[now][u]==0) son[now][u]=++idx;
		now=son[now][u];
	}
	cnt[now]++;
}
inline int query(char t[])
{
	int len=strlen(t),now=0,tmp=0;
	for(int i=0;i<len;i++)
	{
		int u=t[i]-'a';
		if(son[now][u]==0) break;
		tmp+=cnt[son[now][u]];
		now=son[now][u];
	}
	return tmp;
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++)
	{
		scanf("%s",a);
		insert_tree(a);
	}
	while(m--)
	{
		scanf("%s",a);
		printf("%d\n",query(a));
	}
	return 0;
}

应该好理解着

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值