字典树

字典树,map

字典树其实和哈夫曼编码有异曲同工之妙,我们下一次就来说说哈夫曼编码的经典应用《荷马史诗》(noi大水题)。
什么是字典树,就像名字一样可以实现字典的功能,我们可以把一个个字符串像这样存入在这里插入图片描述
这样看起来是不是就清晰了。这个字典树主要有插入和查询这几个操作,我们呢先来看插入

insert

不难发现插入我们要从root开始找,定义一个tree[i][j]数组里面是第i号节点的第j个儿子,j就是我们把字符转化为的数字,如果为0 就说明没这个孩子那么我们就加上这个,如果有就再往下找就欧克了,最后在叶子节点上存我们题里面要去的信息,代码如下

int tot=0;//存总数
int tree[800000][27];//存树
int val[800000]={0};//村存节点的信息 
void insert(char *c){
	int l=strlen(c);
	int root=0;
	for(int i=0;i<l;i++){
		int g=c[i]-'a';
		if(tree[root][g]==0){
			tree[root][g]=++tot;
		}
		root=tree[root][g];
	}
	val[root]=1;
} 

查询

find
这个其实和上面就一样了,我们要查的就是这个读入字符串a是否出现过,或者是谁的前缀,当然字典树加lca肯定就可以求出最长公共前缀,这里我先讲一下查询出现与否。
很简单还是从a一位一位转化为数字,如果tree[root][j]!=0,那么我们就顺着树去找下一位,知道找不到为止。代码如下

int fin(char *c){
  int l=strlen(c);
  int root=0;
  for(int i=0;i<l;i++){
  	int g=c[i]-'a';
  	if(tree[root][g]==0){
  		return 0;
  	}
  	else {
  		root=tree[root][g];
  	}
  }
  if(val[root]>0){
  	if(val[root]==1) {
  		val[root]=2;
  		return 1;
  	}
  	else return 2;
  }
}

这里的题是洛谷的《于是他错误的点名开始了》,很简单的一道题。

map

神奇的map终于来了,我可以这样定义一个map,map<string,int>a,就相当于定义了一个数组 a[string]=int,这个就是把字符和在、数字建立了一个联系,我判断这个字符串有没有出现过就直接,a[…]=0?出现过:没有,当然noi这种级别二点考试如果要考map肯定会卡你的,所以考试是有机会还是手打的好
这是map应用的代码

#include<bits/stdc++.h>
using namespace std;
int n;
string a;
map<string,int>q;

int main(){
	scanf("%d",&n);	
	for(int i=1;i<=n;i++){
		cin>>a;
		q[a]=1;
	}
	int m;
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		cin>>a;
		
		if(q[a]==1) {
			cout<<"OK"<<endl;
			q[a]=2;
		}
		else if(q[a]==2){
			cout<<"REPEAT"<<endl;
		}
		if(q[a]==0) cout<<"WRONG"<<endl;
	}
	return 0;
} ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值