使用位图bitmap记录数的出现情况

位图是一种节省空间的数据结构,常用于网络编程中的IO事件记录。本文通过一个例子展示了如何使用位图记录[0~99]范围内数字的出现情况,对比哈希思想,位图在空间效率上更具优势。通过位运算,仅用4个int单元即可存储0~99的出现状态。代码示例演示了如何通过位图标记和查找出现的数字。

位图

用途
节省空间,一般用于统计数据是否出现过,在网络编程中select函数就是用位图记录IO事件的。
传统我们记录数据就是以桶或者哈希的思想,确实高效,但是某些情况下,这些手段在位图面前还是小巫见大巫了。

模拟场景

假设现在给你一组数,范围在[0 ~ 99]之间,我们如何记录哪些数出现过?(不考虑出现次数)
解:一种可行的方案是使用哈希思想,创建一个数组,利用下标来记录这些数,因为数的范围在 0 ~ 99 , 因此可以创建一个 100 * sizeof(char) 大小的数组,但是这样也用了100Byte大小的空间,有什么更好的方法吗?
使用位图的思想,每一个int类型的数据为4Byte大小,也就是 8 * 4 = 32 bit, 借助每一位的01情况可以表示该数是否出现过。
例如现在给一个数 i = 13;
那么 i / 32 = 0 表示数字 i 应该用第一个int数来表示,
i % 32 = 13表示这个数 i 用第一个数中的第13位(从左往右数)表示

代码示例
#include <iostream>
#include <vector>
using namespace std;

int main() {
	int* arr = new int[4]{ 0 };
	//arr[0] 用于记录 0 ~ 31 arr[1] 记录 32 ~ 63  arr[2] 记录 64 ~ 95
	//存储0 ~ 99只需要4个int单元就可以了
	//现给出一段数据,使用位图记录他们的出现情况
	vector<int> vec{ 2,3,6,44,74,13 };
	for (auto& e : vec) {
		int i = e / 32;//找出对应存放于哪个int单元
		int j = e % 32;//对应的偏移地址
		arr[i] = arr[i] | (1 << (31 - j));//进行位或运算
	}
	for (int i = 0; i < 4; i++) {
		//找出出现过的数
		for (int j = 31; j >= 0; j--) {
			if ((arr[i] >> j) & 1) {
				cout << (i * 32 + 31 - j) << " ";
			}
		}
	}
}
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nepu_bin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值