(小白易通)判断极大数据中一个数是否存在的唯一真神,哈希--位图

引子:哈希应用有很多,我今天来介绍一种比较实用,并且已经有了Bitset库函数的使用--哈希--位图

什么是哈希位图?

位图本质是⼀个直接定址法的哈希表,每个整型值映射⼀个bit位,位图提供控制这个bit的相关接⼝哈希位图是一种使用位图(Bitmap)来存储哈希表中元素存在性的数据结构。位图是一种数据结构,它使用位数组来表示数据,每个位代表一个元素的存在或不存在。在哈希位图中,哈希函数被用来将键映射到位图中的一个位上。如果该位为1,则表示对应的键存在,如果为0,则表示不存在。

实现中需要注意的是:C/C++没有对应位的类型,只能看int/char这样整形类型,我们再通过位运算去 控制对应的⽐特位。⽐如我们数据存到vector中,相当于每个int值映射对应的32个值。

bitset库函数图:

情景引入:给40亿个不重复的⽆符号整数,没排过序。给⼀个⽆符号整数,如何快速判断⼀个数是否在这40亿个 数中。(本题为腾讯/百度等公司出过的⼀个⾯试题)(你会束手无措吗?)

思路:

一,排序和二分查找:首先对40亿个无符号整数进行排序。排序后,可以使用二分查找算法来快速判断给定的整数是否存在于列表中。二分查找的时间复杂度为O(log n)。

二,哈希表:使用哈希表存储这些整数,哈希表可以提供平均O(1)的查找时间复杂度。但是,哈希表可能会遇到冲突,并且需要额外的空间来解决冲突。

三,哈希位图:正如之前所提到的,哈希位图可以用于快速判断一个元素是否存在。由于40亿个整数,每个整数占用4字节,总共需要160GB的内存。如果使用64位整数,每个位可以表示两种状态,因此理论上只需要80GB的内存即可存储这些整数的存在状态。

四,布隆过滤器:布隆过滤器是一种空间效率很高的数据结构,用于测试元素是否是集合中的成员,布隆过滤器有一定的误判率,但可以快速判断元素是否可能不在集合中

本人建议采用哈希位图,也是我们今天要讲的主角!

哈希位图的思路解析(简单):

图一:一个的结构示意图:

图解二:图中数据的单位为比特

一,由此可见只需要将我们的数据插入其中,映射为1就行,

二,对于删去,我们提供rset进行删掉,映射为0就行

三,然后我们用text进行检测!是否存在,0或1进行输出

注意点(误区):位运算符<<,不是看方向,这是从低位向高位移动的部分!

哈希--位图代码部分:

#pragma once
#include<iostream>
#include<bitset>
#include<vector>

namespace bit
{
	//N为2的多少次,即我们的数据量
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_bs.resize(N / 32 + 1);
		}

		// x映射的位标记成1
		void set(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

			_bs[i] |= (1 << j);
		}

		// x映射的位标记成0
		void reset(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

			_bs[i] &= (~(1 << j));
		}

		// x映射的位是1返回真
		// x映射的位是0返回假
		bool test(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

			return _bs[i] & (1 << j);
		}

	private:
		std::vector<int> _bs;
	};

感谢大家收看,下期我们一起学习布尔过滤器以及相关例题如下,期待下次相遇!

有兴趣,记得来看题解:提示,之前我们是只有一个位置,那我们可不可以用二个位置呢?比如00

,01,10,11表示二个变量的清况呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值