所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存储数据,因此可以大大节省存储空间。

基本思想:

  这此我用一个简单的例子来详细介绍BitMap算法的原理。假设我们要对0-7内的5个元素(4,7,2,5,3)进行排序(这里假设元素没有重复)。我们可以使用BitMap算法达到排序目的。要表示8个数,我们需要8个byte。

  1.首先我们开辟一个字节(8byte)的空间,将这些空间的所有的byte位都设置为0

  2.然后便利这5个元素,第一个元素是4,因为下边从0开始,因此我们把第五个字节的值设置为1

  3.然后再处理剩下的四个元素,最终8个字节的状态如下图

  

  4.现在我们遍历一次bytes区域,把值为1的byte的位置输出(2,3,4,5,7),这样便达到了排序的目的

  从上面的例子我们可以看出,BitMap算法的思想还是比较简单的,关键的问题是如何确定10进制的数到2进制的映射图

MAP映射:

  假设需要排序或则查找的数的总数N=100000000,BitMap中1bit代表一个数字,1个int = 4Bytes = 4*8bit = 32 bit,那么N个数需要N/32 int空间。所以我们需要申请内存空间的大小为int a[1 + N/32],其中:a[0]在内存中占32为可以对应十进制数0-31,依次类推:

  a[0]-----------------------------> 0-31

  a[1]------------------------------> 32-63

  a[2]-------------------------------> 64-95

  a[3]--------------------------------> 96-127

  ......................................................

  那么十进制数如何转换为对应的bit位,下面介绍用位移将十进制数转换为对应的bit位:

  1.求十进制数在对应数组a中的下标

  十进制数0-31,对应在数组a[0]中,32-63对应在数组a[1]中,64-95对应在数组a[2]中………,使用数学归纳分析得出结论:对于一个十进制数n,其在数组a中的下标为:a[n/32]

  2.求出十进制数在对应数a[i]中的下标

  例如十进制数1在a[0]的下标为1,十进制数31在a[0]中下标为31,十进制数32在a[1]中下标为0。 在十进制0-31就对应0-31,而32-63则对应也是0-31,即给定一个数n可以通过模32求得在对应数组a[i]中的下标。

  3.位移

  对于一个十进制数n,对应在数组a[n/32][n%32]中,但数组a毕竟不是一个二维数组,我们通过移位操作实现置1

  a[n/32] |= 1 << n % 32
  移位操作:
  a[n>>5] |= 1 << (n & 0x1F)

  n & 0x1F 保留n的后五位 相当于 n % 32 求十进制数在数组a[i]中的下标

代码实现:

  

public class BitMap {

    private static final int N = 10000000;

    private int[] a = new int[N/32 + 1];

    /**
* 设置所在的bit位为1
* @param n
*/
public void addValue(int n){
//row = n / 32 求十进制数在数组a中的下标
int row = n >> 5;
//相当于 n % 32 求十进制数在数组a[i]中的下标
a[row] |= 1 << (n & 0x1F);
} // 判断所在的bit为是否为1
public boolean exits(int n){
int row = n >> 5;
return (a[row] & ( 1 << (n & 0x1F))) != 1;
} public void display(int row){
System.out.println("BitMap位图展示");
for(int i=0;i<row;i++){
List<Integer> list = new ArrayList<Integer>();
int temp = a[i];
for(int j=0;j<32;j++){
list.add(temp & 1);
temp >>= 1;
}
System.out.println("a["+i+"]" + list);
}
} public static void main(String[] args){
int num[] = {1,5,30,32,64,56,159,120,21,17,35,45};
BitMap map = new BitMap();
for(int i=0;i<num.length;i++){
map.addValue(num[i]);
} int temp = 120;
if(map.exits(temp)){
System.out.println("temp:" + temp + "has already exists");
}
map.display(5);
}
}

运行结果如下:

temp:120has already exists
BitMap位图展示
a[0][0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
a[1][1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
a[2][1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
a[3][0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
a[4][0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

应用范围:
  可以运用在快速查找、去重、排序、压缩数据等。

  

BitMap算法详解的更多相关文章

  1. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  2. kmp算法详解

    转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...

  3. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  4. [转] KMP算法详解

    转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段.    我们这里说的K ...

  5. 【转】AC算法详解

    原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...

  6. KMP算法详解(转自中学生OI写的。。ORZ!)

    KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...

  7. EM算法详解

    EM算法详解 1 极大似然估计 假设有如图1的X所示的抽取的n个学生某门课程的成绩,又知学生的成绩符合高斯分布f(x|μ,σ2),求学生的成绩最符合哪种高斯分布,即μ和σ2最优值是什么? 图1 学生成 ...

  8. Tarjan算法详解

    Tarjan算法详解 今天偶然发现了这个算法,看了好久,终于明白了一些表层的知识....在这里和大家分享一下... Tarjan算法是一个求解极大强联通子图的算法,相信这些东西大家都在网络上百度过了, ...

  9. 安全体系(二)——RSA算法详解

    本文主要讲述RSA算法使用的基本数学知识.秘钥的计算过程以及加密和解密的过程. 安全体系(零)—— 加解密算法.消息摘要.消息认证技术.数字签名与公钥证书 安全体系(一)—— DES算法详解 1.概述 ...

随机推荐

  1. Jmeter Ant Task如果报告中有错误,在邮件内容里面直接显示出来 系列2

    由于部门有多个项目,将自动化测试框架运用于多个项目时,希望针对每个项目修改的东西越少越好,为此,做如下修改: D:\apache-jmeter-2.7\extras\jmeter-results-de ...

  2. centos / debian 安装iptables服务

    debian: #使用可参考 https://www.debian.cn/archives/991 #配置文件位于 /etc/iptables #重新配置使用dpkg-reconfigure ipta ...

  3. 转载hibernate 的3种 状态 。。

    转自  http://huangtut.iteye.com/blog/261520  对我有帮助,所以收藏了 Hibernate三种状态的区分,以及save,update,saveOrUpdate,m ...

  4. eclipse 配置动态web项目在servers中运行

    第一步: window->preferences:Server->Runtime Environments窗口,add. 第二步: window->preferences:Proje ...

  5. 【commons-io】File对文件与目录的处理&FileUtis,IOUtils,FilenameUtils工具的使用

    -------------------File的使用-------------- 1.File类对文件的处理 1.1目录结构:  1.2测试对文件Test.txt处理: // 测试文件 @Test p ...

  6. 2018.09.07 bzoj1911: [Apio2010]特别行动队(斜率优化dp)

    传送门 斜率优化dp经典题. 题目中说的很清楚,设f[i]表示前i个数分配出的最大值. 那么有: f[i]=max(f[j]+A∗(sum[i]−sum[j])2+B∗(sum[i]−sum[j])+ ...

  7. 【转】web应用缓慢故障分析

    在这以后里分享一篇关于web应用缓慢的分析过程,感觉挺有用的. 原文出处:http://xjsunjie.blog.51cto.com/999372/751585 友在一家购物网站做运维不久,今日打电 ...

  8. Linux各个版本资源下载

    Linux系统各发行版镜像下载(持续更新) == Linux系统各发行版镜像下载(2014年10月更新),如果直接下载不了,请使用迅雷下载.并且注意,我的下载地址,在  迅雷 里才起作用. Linux ...

  9. svn错误:Can't convert string from 'UTF-8' to native encoding

    如果文件名包含了中文,当执行"svn up ."遇到如下错误时: svn: Can't convert string from 'UTF-8' to native encoding ...

  10. Hive 1.2.1&Spark&Sqoop安装指南

    目录 目录 1 1. 前言 1 2. 约定 2 3. 服务端口 2 4. 安装MySQL 2 4.1. 安装MySQL 2 4.2. 创建Hive元数据库 4 5. 安装步骤 5 5.1. 下载Hiv ...