【数据结构】 ——浅谈位图以及位图原理

一、位图概念

今天学校的课还挺多的,不过我也没怎么听,嘤嘤嘤,好不容易的抽出一点时间整理下位图。进入正题吧

位图(bitset)是一种常见的数据结构,常用在给一个很大范围的数(比如我之前看到一个题是有四十亿个数),判断其中的数是不是在其中。这里就要用到位图,显然这么多得数在内存中是存不下的,我们就得重新想办法。位图在索引、数据压缩有很大的应用。

位图使用数组实现的,数组的每一个元素的每一个二进制位都表示一个数据,0表示该数不存在,1表示该数据存在

二、位图模型

回到我们之前说的问题,有四十亿个数,内存怎么存?位图想到一个办法,一个int型的数字是4个字节,32个比特位,如果我们把每一个比特位标志一个数字,那一个字节就可以标记32个数字(注意:位图不存放这些数据,只是标记是否存在,位图中的数组存放的是二进制数字0或者1)

【数据结构】 ——浅谈位图以及位图原理_第1张图片
40亿个数字大概就是16g,而现在使用位图16g/32大约就是500M左右,内存省掉很多很多,效率也同时提高了

三、位图的设计

如果上的内容你明白了,那设计位图你也应该没啥问题,我们采用vector数组作为底层,这样可以开辟一段连续的空间,而range>>5(range表示的是要统计的数字规模)就相当于除以32,后面+1,是为了防止小于32 的数除以32商为0。

class bitmap 
{
public:
	bitmap(size_t range)  //range表示数的集合大小
	{
		_bit_table.resize((range >> 5) + 1);   //这里表示40亿个数要开多大的空间存储
	}
private:
	vector<int> _bit_table;
};

位图元素的设置
解释都在代码的注释

void setbit(size_t x)
	{
		size_t index = x >> 5;  //算出x在第几个整型位
		size_t n = x % 32;  //在某个整型位的具体位置

		_bit_table[index] |= (1 << n);   //将该具体位置为1,其他位不变
	}

移除该数字
为了移除该数字,我们只需要把该位置为0,其他位不变

void removebit(size_t x)
	{
		size_t index = x >> 5;//算出x在第几个整型位
		size_t n = x % 32; //在某个整型位的具体位置

		_bit_table[index] &=~(1 << n);  //将该位置为0,其余位置为1
	}

位图元素的查找

int find(size_t x)
	{
		size_t index = x >> 5;//算出x在第几个整型位
		size_t n = x % 32; //在某个整型位的具体位置

		return _bit_table[index] & (1 << n);   //返回0或者1
	}

你可能感兴趣的:(C++,数据结构)