| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 位图的实战场景及源码分析 -> 正文阅读 |
|
[数据结构与算法]位图的实战场景及源码分析 |
前言:之前碰到过一道面试题,大概内容如下
刚开始想的时候,处理思路应该很简单,直接把这40亿个数字存储到一个集合中,但是仔细一算,发现并不现实,一个int类型的数字占4个字节,4byte * 40亿 差不多就是16G的大小,占用内存太大,那么还有没有好的办法给解决呢? 1.解决思路一个int类型数字占用4字节,32bit位,那我们能不能用一个bit位来表示一个数字呢? 理论上肯定是可以的,如下图所示: ? 我们用bit0位代表1,一直到31位bit代表数字32,如果当前bit位值为1,则说明存在对应数字。这样的话,一个32bit的int,可以存储32个数字,如果按照这种模型的话,那么上面的40亿个数字使用500多M的空间就可以存放下来。 假如现在需要存放数字1、3、31,那么具体如下 ? 是一个不错的思路,但是上面这种,超过32bit位的数字应该怎么办呢?总不能无限扩bit位吧? 我们可以使用数组来解决这个问题,32bit所组成的数组,如下所示: ? 我们使用这个数组来存放更多的值,理论上来说,无论多少的值(N个数字),只要内存放的下,我们就可以使用int[]来存放,数组的长度等于N/32+1 2.代码实现
获取的话,主要分为两步,第一步:获取数字n在int[]中的row(具体某行);第二步:获取数字n在int[row]中具体的index 3.java中的BitSet实现在java.util包下,有一个叫做BitSet的类,它本质上就是上述位图的实现,我们先来看下其是如何使用的
使用起来非常简单,就我们在前言中提到的问题,就可以用同样的方式来解决,我们可以将这40亿个数字都调用bitSet.set()方法添加进来(如果觉得太多,可以分批次添加),最终调用get方法来进行指定数字查询即可。 3.1 BitSet的构造方法
看了BitSet的构造方法,与上面我们的解决方案有所不同的是,这里采用long[]数组来存放数据,其他没有不同。 默认的话,最大为64,所以对应的long[]数组大小为64 >> 6 = 1。当然,也可以在创建BitSet的时候指定数据大小,这时候数组大小即为(n-1) >> 6 +1 3.2 BitSet.set() 添加数据
使用BitSet添加数据时候,代码并不复杂,基本与上2中的操作是一致的,只不过这里多一个自动扩容的操作,防止数据过大,当前long[]存储不下 3.3 BitSet.get() 查询数据是否在BitSet中
查询数据是否存在的过程,就是按照set的过程进行一遍查询而已,不算复杂,主要就是寻找对应行的对应位所对应的值是否为1,为1说明数据存在,否则,数据不存在 BitSet还提供了很多其他的方法,大家可以自行阅读测试,笔者不再赘述。 参考: |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 5:29:14- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |