走进BitMap-入门好文

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。走进BitMap-入门好文,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

走进BitMap-入门好文

前言

希望读者在阅读本文后能对BitMap有所了解,同时如果本文有不对的地方希望指出我会尽快修改。😅

结构了解

BitMap 多用于大数据量的场景。

举个🌰: 假设我们有10亿的int数据,那么我们需要 4*10亿=40亿字节≈4G空间

BitMap🤣正如直译“位图”一样,非常的形象。下面看一张图
走进BitMap-入门好文

上面的图表示我们存储了数字 3、5

🎈我们用一个bit来表示每一个数字
即:我们声明一个长度为 n 的比特数组,利用下标来表示数字
当数组的第 i 位元素为1时则代表 i 存在

这样是不是就不用每一个数字都占用4字节空间了。

🍟下面对比一下存储的空间
int 类型,存储1个数字需要 4字节=32比特
bit 数组,存储1个数字只需 1比特
相当于节省空间 32 倍
🎃现在如果用 BitMap 来存储10亿数字只需要:4G/32≈125Mb
4G与128M,何等的卧槽

算法了解

🤔那么我们如何存储呢?
上面说到了我们的每一个数字只占1个bit,我们这里用int[]来举🌰
👓假设我们要存储最大数为 n 的一堆数字,那么我们的数组大小为:n / 32 +1

int[] bits = new int[n/32+1];

下面我们如何在一个int中存储32个数字,我们知道int占4字节也就是32bit。一个数字也就对应1bit,列举一下数字存储情况

bits[0] => [0, 31]
bits[1] => [32, 63]
bits[2] => [64, 95]

对于数字 k
对应 bits 的下标 i = k / 32
在下标 i 中的对应位置 j = k % 32
即数字 k 在 bits[k / 32][k % 32] 位置,🤔为什么上面是一维数组这里又是二维数组了。为了方便读者理解,实际上还是一维数组,我们将数组中的每个数字都看成一个二进制,此时就相当于一个二维数组了
走进BitMap-入门好文

// int[] bits = new int[n/32+1];
public void add(int k) {
	bits[k >> 5] |= 1 << (k & 0x1f);
}

k >> 5 相当于 k / 32
k & 0x1f 相当于 k % 32
1 << (k & 0x1f) 相当于 2k & 0x1f,即将 k & 0x1f 位数字标记
整个式子就是:将 bits 中下标为 k/32 的数字从右往左数第 k & 0x1f 位二进制数标记为1
且重复标记答案一样

上面讲解了如何存储,那么我们如何取出来呢🤔
🌰我们现在要判断是否存储了数字 k

// int[] bits = new int[n/32+1];
public boolean has(int k) {
	return (bits[k >> 5] >> (k & 0x1f) & 1) == 1;
}

整个式子意思是判断 bits 中下标为 k/32 的数字从右往左数第 k & 0x1f 位二进制数是否为1

结语

🎉到此我们了解了 BitMap,若要用long做数组也行只是确定位置的地方略有区别而已。
我们发现,假设最大数是十亿,那么我们至少要十亿个 bit 位才行,那么在数据比较稀疏的情况下表现并没有那么的优秀。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/195214.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!