【c++学习】位图/布隆过滤器

本文介绍了位图作为图像存储方式的基本概念,以及其在数据表示中的应用,特别是位图如何通过哈希思想用于海量数据判断。随后详细讲解了布隆过滤器的工作原理和使用,展示了其通过多个哈希函数减少数据冲突的特性,适用于集合成员查询的场景。
摘要由CSDN通过智能技术生成

位图的概念

位图是一种图像存储方式,也称为二维位数组。它将图像中的每个像素点都表示为一个二进制位。位图可以包含黑白像素或彩色像素,每个像素的颜色信息都用二进制数据来表示。
在位图中,每个像素都有一个对应的二进制数值,通常是用几个字节来表示,表示的数值范围决定了颜色的种类和精度。例如,对于黑白图像,每个像素只需要1位来表示,0代表黑色,1代表白色;对于彩色图像,常见的有24位颜色深度,每个像素用3个字节来表示,分别代表红、绿、蓝三个通道的亮度。位图的宽度和高度决定了图像的大小。

位图的应用

位图思想和哈希思想类似,将数据进行映射,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
在这里插入图片描述
如图题。数据量特别大,我们就可以运用位图:数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在
可以创建一个整形数组。
在这里插入图片描述

代码实现:

	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_bit.resize(N/32+1,0);
		}
		void set(size_t x)
		{
			assert(x <= N);
			size_t i = x / 32;
			size_t j = x % 32;
			_bit[i] |= (1 << j);
		}
		bool test(size_t x)
		{
			assert(x <= N);

			size_t i = x / 32;
			size_t j = x % 32;

			return _bit[i] & (1 << j);
		}
	private:
		vector<int> _bit;
	};

布隆过滤器

布隆过滤器使用一个很长的二进制向量和一组哈希函数来表示一个集合。当一个元素被加入集合时,通过哈希函数将元素映射到二进制向量上的几个位置,将这些位置标记为1。使用哈希函数的随机性,可以使得多个元素映射到同一个位置的概率很低。
当需要判断一个元素是否在集合中时,同样使用哈希函数将元素映射到二进制向量上的位置,然后检查这些位置是否都为1。如果都为1,表示该元素可能在集合中;如果有一个位置为0,那么该元素一定不在集合中。

布隆过滤器的应用

将大量将要进行映射的数据,通过两种或多种哈希函数进行算值,映射在一个数组中。
如下图下x,y经过Hash函数取模之后分别对应了两个位置进行映射,这样可以大大降低数据冲突情况!(x,y可以是任意数据,字符串,整形等等)
在这里插入图片描述
代码实现:

	struct HashFuncBKDR
	{
		// BKDR
		size_t operator()(const string& s)
		{
			size_t hash = 0;
			for (auto ch : s)
			{
				hash *= 131;
				hash += ch;
			}

			return hash;
		}
	};

	struct HashFuncAP
	{
		// AP
		size_t operator()(const string& s)
		{
			size_t hash = 0;
			for (size_t i = 0; i < s.size(); i++)
			{
				if ((i & 1) == 0) // 偶数位字符
				{
					hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));
				}
				else              // 奇数位字符
				{
					hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));
				}
			}

			return hash;
		}
	};

	struct HashFuncDJB
	{
		// DJB
		size_t operator()(const string& s)
		{
			size_t hash = 5381;
			for (auto ch : s)
			{
				hash = hash * 33 ^ ch;
			}

			return hash;
		}
	};
	template<size_t N, class K = string, class Hash1 = HashFuncBKDR, class Hash2 = HashFuncAP, class Hash3 = HashFuncDJB>
	class Bloom
	{
	public:
		void Set(const K& s)
		{
			size_t hash1 = Hash1()(s) %	M;
			size_t hash2 = Hash2()(s) % M;
			size_t hash3 = Hash3()(s) % M;
			_bl->set(hash1);
			_bl->set(hash2);
			_bl->set(hash3);
		}
		bool Test(const K& s)
		{
			size_t hash1 = Hash1()(s) % M;
			if (_bl->test(hash1) == false)
				return false;

			size_t hash2 = Hash2()(s) % M;
			if (_bl->test(hash2) == false)
				return false;

			size_t hash3 = Hash3()(s) % M;
			if (_bl->test(hash3) == false)
				return false;

			return true;
		}
	private:
		static const size_t M = 10 * N;
		std::bitset<M>* _bl = new std::bitset<M>;
	};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值