【Java难点攻克】「海量数据计算系列」如何使用BitMap在海量数据中对相应的进行去重、查找和排序实战

news2024/9/23 15:23:10

BitMap(位图)的介绍

BitMap从字面的意思,很多人认为是位图,其实准确的来说,翻译成基于位的映射,其中数据库中有一种索引就叫做位图索引。

在具有性能优化的数据结构中,大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美。但是数据量大了,内存就不够了。此外,可以使用类似外排序来解决问题的,由于要走IO所以时间上又不行。

所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素。由于采用了Bit为单位来存储数据,因此在存储空间方面,可以节省。

BitMap(位图)的应用

  • 1)可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下。
  • 2)去重数据而达到压缩数据

BitMap(位图)的原理

上面说了BitMap的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素。由于采用了Bit为单位来存储数据。

BitMap(位图)的案例

假设有这样一个需求:在20亿个随机整数中找出某个数m是否存在其中,并假设32位操作系统,4G内存

在Java中,int占4字节,1字节=8位(1 byte = 8 bit)

  • 如果每个数字用int存储,那就是20亿个int,因而占用的空间约为 (2000000000*4/1024/1024/1024)≈7.45G

  • 如果按位存储就不一样了,20亿个数就是20亿位,占用空间约为 (2000000000/8/1024/1024/1024)≈0.233G

如何表示一个数呢

每一位表示一个数,0表示不存在,1表示存在,这正符合二进制

这样可以很容易表示{1,2,4,6}这几个数:

计算机内存分配的最小单位是字节,也就是8位,那如果要表示{12,13,15}怎么办呢?当然是在另一个8位上表示了:

这样的话,好像变成一个二维数组了

1个int占32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32] 即可存储,其中N表示要存储的这些数中的最大值,于是乎:

  • tmp[0]:可以表示0~31

  • tmp[1]:可以表示32~63

  • tmp[2]:可以表示64~95

如此一来,给定任意整数M,那么M/32就得到下标,M%32就知道它在此下标的哪个位置。

添加

怎么把一个数放进去呢?例如,想把5这个数字放进去,怎么做呢?

首先,5/32=0,5%32=5,也是说它应该在tmp[0]的第5个位置,那我们把1向左移动5位,然后按位或

换成二进制就是

这就相当于 86 | 32 = 118

86 | (1<<5) = 118
b[0] = b[0] | (1<<5)

要想插入一个数,将1左移带代表该数字的那一位,然后与原数进行按位或操作

简化一下,就是 86 + (5/8) | (1<<(5%8))

因此,公式可以概括为:p + (i/8)|(1<<(i%8)) 其中,p表示现在的值,i表示待插入的数

清除

如果要清除该怎么做呢?

还是上面的例子,假设我们要6移除,该怎么做呢?

从图上看,只需将该数所在的位置为0即可

1左移6位,就到达6这个数字所代表的位,然后按位取反,最后与原数按位与,这样就把该位置为0了

b[0] = b[0] & (~(1<<6))

b[0] = b[0] & (~(1<<(i%8)))

查找

每一位代表一个数字,1表示有(或者说存在),0表示无(或者说不存在)。通过把该为置为1或者0来达到添加和清除的效果,那么判断一个数存不存在就是判断该数所在的位是0还是1

假设,我们想知道3在不在,那么只需判断 b[0] & (1<<3) 如果这个值是0,则不存在,如果是1,就表示存在。

Bitmap快速排序

假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复),我们就可以采用Bit-map的方法来达到排序的目的。要表示8个数,我们就只需要8个Bit(1Bytes),首先我们开辟1Byte的空间,将这些空间的所有Bit位都置为0,然后将对应位置为1。最后,遍历一遍Bit区域,将该位是一的位的编号输出(2,3,4,5,7),这样就达到了排序的目的,时间复杂度O(n)。

优点:

  • 运算效率高,不需要进行比较和移位;
  • 占用内存少,比如N=10000000;只需占用内存为N/8=1250000Byte=1.25M

缺点:

  • 所有的数据不能重复。即不可对重复的数据进行排序和查找。
  • 只有当数据比较密集时才有优势

Bitmap快速去重

  • 20亿个整数中找出不重复的整数的个数,内存不足以容纳这20亿个整数。

  • 首先,根据“内存空间不足以容纳这05亿个整数”我们可以快速的联想到Bit-map。下边关键的问题就是怎么设计我们的Bit-map来表示这20亿个数字的状态了。其实这个问题很简单,一个数字的状态只有三种,分别为不存在,只有一个,有重复。因此,只需要2bits就可以对一个数字的状态进行存储了,假设我们设定一个数字不存在为00,存在一次01,存在两次及其以上为11。那我们大概需要存储空间2G左右。

  • 接下来的任务就是把这20亿个数字放进去(存储),如果对应的状态位为00,则将其变为01,表示存在一次;如果对应的状态位为01,则将其变为11,表示已经有一个了,即出现多次;如果为11,则对应的状态位保持不变,仍表示出现多次。

  • 最后,统计状态位为01的个数,就得到了不重复的数字个数,时间复杂度为O(n)。

快速查找

int数组中的一个元素是4字节占32位,那么除以32就知道元素的下标,对32求余数(%32)就知道它在哪一位,如果该位是1,则表示存在.

Bitmap的场景总结

  • Bitmap主要用于快速检索关键字状态,通常要求关键字是一个连续的序列(或者关键字是一个连续序列中的大部分), 最基本的情况,使用1bit表示一个关键字的状态(可标示两种状态),但根据需要也可以使用2bit(表示4种状态),3bit(表示8种状态)。

  • Bitmap的主要应用场合:表示连续(或接近连续,即大部分会出现)的关键字序列的状态(状态数/关键字个数 越小越好)。

  • 32位机器上,对于一个整型数,比如int a=1 在内存中占32bit位,这是为了方便计算机的运算。但是对于某些应用场景而言,这属于一种巨大的浪费,因为我们可以用对应的32bit位对应存储十进制的0-31个数,而这就是Bit-map的基本思想。Bit-map算法利用这种思想处理大量数据的排序、查询以及去重。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LiteOS-M内核

简介 OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核&#xff0c;具有小体积、低功耗、高性能的特点&#xff0c;其代码结构简单&#xff0c;主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等&#xff0c;分为硬件相关层以及硬件无关层&…

[附源码]计算机毕业设计校园快递柜存取件系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

多线程复习——进程线程(上)

目录 一、进程是啥?跑起来的程序 二、进程是怎么管理的?描述组织 三、进程的PCB里有啥? 四、进程的调度是咋进行?时间管理大师 五、进程的独立性是咋回事? 六、进程之间如何通信? 一、进程是啥?跑起来的程序 进程(process) 也叫做 任务(task).对于操作系统来说 一个…

牛客网刷题(BC72、BC18、BC83、BC84、BC41、BC31、BC17、BC6)

目录 一、BC72 平均身高 二、BC18 计算带余除法​编辑 三、BC83 被5整除问题​编辑 四、BC84计算y的值 五、BC41 你是天才吗&#xff1f; 六、BC31 发布信息 七、BC17 计算表达式的值 八、BC6 小飞机 **太简单的题就没有文字叙述了~ 一、BC72 平均身高 #define _CRT_S…

[附源码]Python计算机毕业设计Django人体健康管理app

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

力扣(LeetCode)134. 加油站(C++)

贪心 考虑暴力&#xff0c;枚举所有点作为起点&#xff0c;每个点先加油&#xff0c;再尝试前往下一个点&#xff0c;剩余油量大于等于 000 &#xff0c;就可以走下去。枚举所有点的所有路径&#xff0c;时间复杂度 O(n2)O(n^2)O(n2) &#xff0c;对于本题规模 TLETLETLE 。 …

Redis常见错误

目录 一、(error) NOAUTH Authentication required. 二、(error) ERR unknown command keys* 三、(error) ERR invalid password 一、(error) NOAUTH Authentication required. 错误原因&#xff1a;没有使用密码登录认证 使用命令&#xff1a; auth 你自己的密码 如果密码…

【人工智能】确定型推理

确定性推理&#xff08;Deterministic Reasoning&#xff09;目录一、推理基本概念二、推理逻辑基础1. 命题逻辑&#xff08;Propositional Logic&#xff09;2. 谓词逻辑&#xff08;Predicate Logic&#xff09;3. 推理的控制策略(i) 推理方向(a) 正向推理&#xff1a;已知事…

[附源码]Python计算机毕业设计SSM教务一点通管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

制作一个简单HTML个人网页网页——人物介绍梵高(HTML+CSS)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

c++中的cin和getline()函数

cin cin 输入接触到第一个非空格字符时开始阅读&#xff0c; 当遇到下一个空格字符&#xff08;空格、制表符、换行符&#xff09;时就会停止读取&#xff0c; #include<iostream> using namespace std;int main() {string s;printf("输入:\n");cin >>…

[论文阅读] 颜色迁移-颜色空间的选择

[论文阅读] 颜色迁移-颜色空间的选择 论文: [Colour Spaces for Colour Transfer] 本文将颜色迁移方法分为了2大类: 一是直接3D颜色迁移方法二是转换为3个1D颜色迁移方法 对于第二种方法, 颜色空间的选择对颜色迁移结果有很大的影响, 如下所示为 RGB 和 Lab 颜色空间的结果…

使用Express框架操作MongoDB数据库

前言 1、NoSQL数据库&#xff1a;非关系型数据库。数据的组织形式不是二维表格。即Not Only SQL&#xff0c;不能使用SQL语句操作数据。适合存储超大 规模、数据长度不确定的数据&#xff0c;数据没有规定的格式&#xff0c;不需要进行任何的设置就可以自由的横向扩展 2、什…

[附源码]计算机毕业设计校园服装租赁系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

G1D30-NLP(Tokenizer)DP(交叠子问题)

一、NLP &#xff08;一&#xff09;bert中一些标记 1、[SEP] 用于断句&#xff0c;其真实效果&#xff0c;有待考究&#xff0c;因为有segment embedding 2、[CLS] 生成一个向量&#xff0c;用来进行文本分类 &#xff08;二&#xff09;AutoTokenizer 关于tokenizer更…

JMeter入门教程(16)——非GUI运行

文章目录1.任务背景2.任务目标3.任务实操1.任务背景 JMeter的场景运行方式分为两种&#xff0c;一种是GUI&#xff08;视窗运行&#xff0c;即我们可以看到的运行界面&#xff09;方式&#xff0c;另一种是非GUI&#xff08;命令窗口&#xff09;方式运行&#xff0c;在Window…

HTML网页大作业代码【免费代码已上传】

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

[附源码]计算机毕业设计校园便携系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于springboot的智慧养老平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;html、Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#…

SpringBoot+Vue项目便捷洗衣服务平台

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…