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

一、位图概念

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

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

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

二、位图模型

回到我们之前说的问题,有四十亿个数,内存怎么存?位图想到一个办法,一个int型的数字是4个字节,32个比特位,如果我们把每一个比特位标志一个数字,那一个字节就可以标记32个数字(注意:位图不存放这些数据,只是标记是否存在,位图中的数组存放的是二进制数字0或者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
	}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
位图是一种用于存储和操作大量布尔值(true/false)的数据结构。在计算机科学中,位图通常被用于表示一个集合,其中每个元素都对应于一个位(二进制位),如果该元素在集合中,则对应位的值为1,否则为0。使用位图可以极大地减少空间占用,并且可以快速进行一些集合操作,例如并集、交集、差集等。 在Python中,可以使用内置的`array`模块创建位图。该模块提供了一种称为“signed char”的数据类型,它只占用一个字节,可以存储8个布尔值。因此,我们可以将一个大的布尔数组压缩到相对较小的内存空间中。 下面是一个简单的示例,演示如何使用array模块创建一个位图,并执行一些基本操作: ```python import array # 创建一个包含100个布尔值的位图 bit_array = array.array('b', [0] * 100) # 设置第10个元素为True bit_array[9] = 1 # 检查第10个元素是否为True if bit_array[9]: print("第10个元素为True") # 计算位图中所有为True的元素的数量 count = sum(bit_array) print("位图中共有{}个元素为True".format(count)) ``` 注意,在上面的示例中,我们使用'b'作为数组的类型代码,表示signed char类型。这意味着每个元素只占用一个字节。如果我们需要存储更多的布尔值,可以尝试使用其他类型代码,例如'B'(unsigned char)或'i'(signed int)。但是要注意,使用更大的数据类型会占用更多的内存空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值