【算法与数据结构专场】BitMap算法基本操作代码实现
上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下【算法与数据结构专场】BitMap算法介绍
这篇我们来讲一下BitMap这个数据结构的代码实现。
回顾下数据的存储原理
一个二进制位对应一个非负数n,如果n存在,则对应的二进制位的值为1,否则为0。
这个时候,我们的第一个问题:
我们在使用byte,int,short,long等这些数据类型在存储数据的时候,他们最小的都要占用一个字节的内存,也就是8个bit,也就是说,最小的操作单位是8个bit。根本就没有可以一个一个bit位操作的数据类型啊。
在Java的bitMaP实现中,它采用的是用一个long数据来进行存储的。一个long占用8个字节,即64bit,所以一个long可以存储64个数。例如 arr 是一个long 类型的数组,则 arr[0]可以存 0 ~ 63,arr[1]可以存64 ~127,以此类推。
不过,我们就采用byte数组的来存吧。一个byte占用一个字节,即8bit,可以存8个数字。
当然,你要采用long数组来存也可以。在实现上可以说是一样的。
例如我们要存储(1,3,5,7,8,10)时,他们的内存如下所示。
下面我们就来讲讲如何对一个一个位进行操作的。
如何向bitmap中添加一个数值
我们先来说说如何在bitmap中如何添加一个数值的问题,例如我们我们要添加n=14。
这个其实很简单,我们先找到n在arr数组中的下标index,显然index = 1。然后再找到n在arr[index]中的位置position,显然这里position = 6。
这里还是可以很容易找出index和position的公式的。即
index = n / 8 = n >> 3。
position = n % 8 = n & 0x07。
接下来我们把1向右移动position个二进制位,然后把所得的结果和arr[index]做“或(or)”操作就可以了。如下图
这里有个需要注意的地方,在画图的时候,为了方便,我们是把左边的位当作低位,右边的位当作高位来算了。不过在实际的存储中,左边的才是存高位,而右边的存的是低位。所以在我们的代码实现中,我们所说的右移对应代码的左移。
代码实现
//添加数据的操作
public void add(int n){
//用>>的操作是,运算会比较快
int index = n >> 3;
int position = n & 0x07;
//把1右移和做or操作两步一起
//即 << 对应上图的右移,实际上<<是左移符。
arr[index] |= 1 << position;
}
知道了add操作,其他的操作差不多类似。
当然,我们实现的add操作只是简单的实现一下,假如你要严谨地实现的话,还是需要很多异常的判断的。例如判断这个数是否是非负数,判断arr数组是否下标越界,进行容量的扩充等等。有兴趣的可以严谨去实现一下。
删除操作。
我们只需要把对应的二进制的1变成0就可以了。
我们可以把1右移(代码中对应左移)后的结果取反,然后与arr[index]做“与”操作就可以了。代码如下:
public void delete(int n){
int index = n >> 3;
int position = n & 0x07;
arr[index] &= ~(1 << position);
}
判断是否存在操作
我们把1右移之后,把结果和arr[index]做“与”操作,如何结果不为0,则证明存在,否则就不存在。
public boolean contain(int n){
int index = n >> 3;
int position = n & 0x07;
return (arr[index] & (1 << position)) != 0;
}
三个最基本的操作代码基本实现了。
希望大家能够去实践一下。
全部代码:
public class BitMap {
private byte[] arr;
//容量,即最多能够存多少个数据
private int capacity;
public BitMap(int capacity) {
this.capacity = capacity;
//一个byte可以存8个数据,capacity实际上指的是多少个bit
arr = new byte[(capacity / 8 + 1)];
}
//添加数据的操作
public void add(int n){
//用>>的操作是,运算会比较快
int index = n >> 3;
int position = n & 0x07;
//把1右移和做or操作两步一起
//即 << 对应上图的右移,实际上<<是左移符。
arr[index] |= 1 << position;
}
public void delete(int n){
int index = n >> 3;
int position = n & 0x07;
arr[index] &= ~(1 << position);
}
public boolean contain(int n){
int index = n >> 3;
int position = n & 0x07;
return (arr[index] & (1 << position)) != 0;
}
}
问题
大家看了以上的代码,有没发现一些问题呢?
例如我们只在bitmap存储1个数,并且存的数值是2000000000,我们就会在第2000000000个二进制把0改为1。也就是说arr数组的大小至少为2000000000/8+1。可是这时候前面的二进制位并没有存数据,那不是超级超级浪费资源?
所以说,像我们上面的那种写法可以说是暴力写法,没有经过任何优化,实际上,在Java自带的bitMap中是有很多优化的,并不会像我们上面实现的代码一样那么浪费空间资源。有兴趣的可以研究下。
至于如何优化,我会在之后的文章讲,尽情期待。
获取更多原创文章,可以关注下我的公众号:苦逼的码农,我会不定期分享一些资源和软件等。后台回复礼包送你一份时下热门的资源大礼包同时也感谢把文章介绍给更多需要的人
【算法与数据结构专场】BitMap算法基本操作代码实现的更多相关文章
- python算法与数据结构-选择排序算法(33)
一.选择排序的介绍 选择排序(Selection sort)是一种简单直观的排序算法.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素, ...
- python算法与数据结构-希尔排序算法(35)
一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...
- 大数据排序算法:外部排序,bitmap算法;大数据去重算法:hash算法,bitmap算法
外部排序算法相关:主要用到归并排序,堆排序,桶排序,重点是先分成不同的块,然后从每个块中找到最小值写入磁盘,分析过程可以看看http://blog.csdn.net/jeason29/article/ ...
- python算法与数据结构-算法介绍(31)
一.算法和数据结构 什么是算法和数据结构?如果将最终写好运行的程序比作战场,我们程序员便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰:兵法!故,数据结构和算法是一 ...
- 海量数据处理-BitMap算法
一.概述 本文将讲述Bit-Map算法的相关原理,Bit-Map算法的一些利用场景,例如BitMap解决海量数据寻找重复.判断个别元素是否在海量数据当中等问题.最后说说BitMap的特点已经在各个场景 ...
- 算法——001BitMap(位图)算法
哈希表在查找定位操作上具有O(1)的常量时间,常用于做性能优化,但是内存毕竟是有限的,当数据量太大时用哈希表就会内存溢出了.而考虑对这些大数据进行存盘分批处理又有IO上的开销,性能又不能满足要求.这个 ...
- 程序员代码面试指南 IT名企算法与数据结构题目最优解
原文链接 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮 ...
- 数据结构(DataStructure)与算法(Algorithm)、STL应用
catalogue . 引论 . 数据结构的概念 . 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 二叉树 . 物理结构实例 3.1 链表 单向线性链表 单向循环链表 双向线性链表 双向 ...
- 经典算法题每日演练——第十一题 Bitmap算法
原文:经典算法题每日演练--第十一题 Bitmap算法 在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美, 但是在特定的场 ...
随机推荐
- POJ 3751 JAVA
题意: 对于给定的采用”yyyy/mm/dd”加24小时制(用短横线”-”连接)来表示日期和时间的字符串, 请编程实现将其转换成”mm/dd/yyyy”加12小时制格式的字符串,末尾加上pm或者am. ...
- Ubuntu 服务器设置软件多用户访问
假设在用户A下安装了软件xx 路径写入$home/.bashrc 这时该软件只有该用户可以使用 若要其他用户也能使用,只需要将该.bashrc拷贝到其他user的$home目录就行了
- git cannot lock ref
参考博客:https://blog.csdn.net/lindexi_gd/article/details/79213042 错误原文: cannot lock ref ‘refs/remotes/o ...
- hadoop2-elasticsearch的安装
本文主要讲elasticsearch-2.2.1的安装过程. 准备工作: 1.搭建虚拟机 你需要先参考 hadoop2集群环境搭建 把你的虚拟机搭建起来-hadoop环境可以先不用搭建(完成步骤1到步 ...
- STS(Spring Tool Suite)下SSM(Spring+SpringMVC+Mybatis)框架搭建(一)
最近在用SSM框架做一个网站,就顺便把自己要做的笔记需要了解的东西都写了下来,看看对大家学习SSM框架有没有帮助. 开发环境: 1.win10 64位 2.spring-tool-suite-3.9. ...
- matlab安装 macos
http://pan.baidu.com/s/1o6qKdxo内附安装说明Matlab R2014A Mac & Linux 破解版 readme文件有流程!可以安装
- 数据库mysql大全(高级版)
1.说明:创建数据库 CREATE DATABASE database-name .说明:删除数据库 drop database dbname .说明:备份sql server --- 创建 备份数据 ...
- MySql解除安全模式:Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
在修改一条数据字段时报错: Error Code: 1175. You are using safe update mode and you tried to update a table witho ...
- threejs立方体贴图产生边缘锯齿问题
threejs立方体贴图产生边缘锯齿问题 立方体贴图边缘锯齿 解决后 经过试验测试发现, textureGrass.wrapS和 textureGrass.wrapT属性导致的. 解决方法1: 删掉t ...
- Razor Page Library:开发独立通用RPL(内嵌wwwroot资源文件夹)
ASP.NET Core知多少系列:总体介绍及目录 Demo路径:GitHub-RPL.Demo 1. Introduction Razor Page Library 是ASP.NET Core 2. ...