位图介绍与实现

Posted 可乐不解渴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位图介绍与实现相关的知识,希望对你有一定的参考价值。

位图与布隆过滤器

位图的概念

位图的本质其实就是直接定值法的哈希,就是用每一个比特位来存放某种状态(通常用来表示该元素是否存在),由于表示每一个数据是否存在只需要使用一个比特位,其优点是节省空间,适用于海量数据,数据无重复的场景。

namespace ZJ

	template<size_t N>
	class BitSet//位图,解决不了字符串的情况
	
	public:
		BitSet();
		void set(const size_t& val);//设置位
		void reset(const size_t& val);取消位
		bool test(const size_t& val)const;//检查该值是否在位图中存在
	public:
		std::vector<int> _bits;	//按位存储的哈希表
	;

位图的实现

构造函数

在我们使用位图时,首先要做的第一件事就是根据所需要N位数来创建N位的位图,并将所有的位图的所有位置都设置为0(即每一个位上表示的数据不存在)。
但是一个整形是有32个比特位的,因此用户输入N个位的位图就需要用到N/32个整形,但是实际我们所需要的整形个数是N/32+1,因为用户输入的位数可能小于1个整形所含盖的位数。
例如:当用户输入的位数是48位时,此时我们就需要创建两个整形(int),即需要 48 / 32 + 1 = 2,共计64个比特位。

		BitSet()
		
			_bits.resize(N / 32 + 1, 0);
		

set

set函数用于将某个值所映射的位置设置为存在状态,即对应的比特位设置为1。

设置x值对应到位图中指定的位的方法如下:

  1. 计算出该数(x)位于第 i 个整数的第 j 个比特位。
  2. 将1左移 j 位后与第 i 个整数进行或运算即可。

具体如下图所示:

		// 把x映射的位标记成1
		void set(size_t x)
		
			assert(x < N);

			// 算出x映射的位在第i个整数
			// 算出x映射的位在这个整数的第j个位
			size_t i = x / 32;
			size_t j = x % 32;

			// _bits[i] 的第j位标记成1,并且不影响他的其他位
			_bits[i] |= (1 << j);
		

reset

set函数用于将某个值所映射的比特置为不存在状态,即置为0。

清空x值对应到位图中指定的位的方法如下:

  1. 计算出该值对应位图当中第 i 个整数的第 j 个比特位。
  2. 将1左移 j 位再取反后与第 i 个整数进行与运算即可。

具体如下图所示:

		void reset(size_t x)
		
			assert(x < N);

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

			// _bits[i] 的第j位标记成0,并且不影响他的其他位
			_bits[i] &= (~(1 << j));
		

test

tes函数用于获取x值对应的比特位的数据是否存在。

获取位图中x值对应指定的位的状态的方法如下:

  1. 计算出该位位于第 i 个整数的第 j 个比特位。
  2. 将1左移 j 位后与第 i 个整数进行与运算得出结果。
  3. 若结果非0,则该位对应的数据存在,否则该不存在。

		bool test(size_t x)
		
			assert(x < N);

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

			// 如果第j位是1,结果是非0,非0就是真
			// 如果第j为是0,结果是0,0就是假
			return _bits[i] & (1 << j);
		

下期预告:C++11!!!

以上是关于位图介绍与实现的主要内容,如果未能解决你的问题,请参考以下文章

位图介绍与实现

Redis学习 —— 管道 与 位图

位图数据结构

STL详解(十四)—— bitset(位图)的介绍与使用

用于位图管理的 C++ STL 类

位图的介绍及实现