栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++STL unordered

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++STL unordered

写题的时候经常要判断一个区间或者一条边/点是否存在。会写出这种代码

unordered_map, int>m1;
unordered_mapm2;

很明显报错了。理由是STL unordered_map/set只对基本数据类型和string做了hash。也就是不仅是自定义类型,pair这种的hash也要自己写。

首先来分析unordered_map/set的参数

unordered_set,typename _Keyeq=equal_to<_Kty>,typename _Allocator<_Kty>>
unordered_map,typename _Keyeq=equal_to<_Kty>,typename _Allocator<_Kty>>

以unordered_map为例,

前两个参数为(key,value)键值对。

第三个参数即为hash标准,

而第四个参数为判断元素相同的函数 因为map和set需要判断新加入元素和容器内元素的键值是否相同来安排元素的位置。

也就是说,我们需要一个仿函数实现该复杂类型的hash,同时还需要给这个类型重载==(equal)以至于map/set可以安排他的位置。

得到hash值可以通过STL自带的hash模板函数,但是只能对基本数据类型和string做hash。不过我们可以分解复杂类型内的基本类型,用复杂类型的基本类型组合成新的hash值代表这个复杂类型。

hash()(valua)

补充:所谓仿函数也就是重载在一个结构体/类中的运算符函数。

struct node {
	int x, y;
	int operator==(const node& a)const {//自定义类型要加==重载
		if(x==a.x&&y==a.y)
		return 1;
	}
};
struct hashf {
	template
	int operator()(const pair& a)const {
		return hash()(a.first)*13 ^ hash()(a.second)*31;
	}

	int operator()(const node& a)const {
		return hash()(a.x)*13 ^ hash()(a.y)*31;//基本类型组合成新的hash
	}
};
unordered_map, int,hashf>m1;
unordered_mapm2;

这样就可以实现,对pair和自定义类型的hash了

注意,如果hash函数太弱的的话会频繁产生hash冲突,复杂度会大幅提高。


但是map和set不需要这么麻烦,map可以直接存入pair,是因为,map和set只需要重载比较运算符进行排序,而unordered_map底层是hash表,所以需要hash值。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/935283.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号