一、概述
本文将讲述Bit-Map算法的相关原理,Bit-Map算法的一些利用场景,例如BitMap解决海量数据寻找重复、判断个别元素是否在海量数据当中等问题.最后说说BitMap的特点已经在各个场景的使用性。
二、Bit-Map算法
先看看这样的一个场景:给一台普通PC,2G内存,要求处理一个包含40亿个不重复并且没有排过序的无符号的int整数,给出一个整数,问如果快速地判断这个整数是否在文件40亿个数据当中?
问题思考:
40亿个int占(40亿*4)/1024/1024/1024 大概为14.9G左右,很明显内存只有2G,放不下,因此不可能将这40亿数据放到内存中计算。要快速的解决这个问题最好的方案就是将数据搁内存了,所以现在的问题就在如何在2G内存空间以内存储着40亿整数。一个int整数在java中是占4个字节的即要32bit位,如果能够用一个bit位来标识一个int整数那么存储空间将大大减少,算一下40亿个int需要的内存空间为40亿/8/1024/1024大概为476.83 mb,这样的话我们完全可以将这40亿个int数放到内存中进行处理。
具体思路:
1个int占4字节即4*8=32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32]即可存储完这些数据,其中N代表要进行查找的总数,tmp中的每个元素在内存在占32位可以对应表示十进制数0~31,所以可得到BitMap表:
tmp[0]:可表示0~31
tmp[1]:可表示32~63
tmp[2]可表示64~95
.......
那么接下来就看看十进制数如何转换为对应的bit位:
假设这40亿int数据为:6,3,8,32,36,......,那么具体的BitMap表示为:

那么怎么快速定位它的索引呢。如果找到它的索引号,又怎么定位它的位置呢。Index(N)代表N的索引号,Position(N)代表N的所在的位置号。

Index(N) = N/8 = N >> 3;

Position(N) = N%8 = N & 0x07;

add方法:

    public void add(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3; // num%8得到在byte[index]的位置
int position = num & 0x07; //将1左移position后,那个位置自然就是1,然后和以前的数据做|,这样,那个位置就替换成1了。
bits[arrayIndex] |= 1 << position;
}

code:

public class BitMap {
//保存数据的
private byte[] bits; //能够存储多少数据
private int capacity; public BitMap(int capacity){
this.capacity = capacity; //1bit能存储8个数据,那么capacity数据需要多少个bit呢,capacity/8+1,右移3位相当于除以8
bits = new byte[(capacity >>3 )+1];
} public void add(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3; // num%8得到在byte[index]的位置
int position = num & 0x07; //将1左移position后,那个位置自然就是1,然后和以前的数据做|,这样,那个位置就替换成1了。
bits[arrayIndex] |= 1 << position;
} public boolean contain(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3; // num%8得到在byte[index]的位置
int position = num & 0x07; //将1左移position后,那个位置自然就是1,然后和以前的数据做&,判断是否为0即可
return (bits[arrayIndex] & (1 << position)) !=0;
} public void clear(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3; // num%8得到在byte[index]的位置
int position = num & 0x07; //将1左移position后,那个位置自然就是1,然后对取反,再与当前值做&,即可清除当前的位置了.
bits[arrayIndex] &= ~(1 << position); } public static void main(String[] args) {
BitMap bitmap = new BitMap(100);
bitmap.add(7);
System.out.println("插入7成功"); boolean isexsit = bitmap.contain(7);
System.out.println("7是否存在:"+isexsit); bitmap.clear(7);
isexsit = bitmap.contain(7);
System.out.println("7是否存在:"+isexsit);
}
}

每个byte存8个数字,相对于int类型来说,节省了32倍的存储空间

存储数据范围,就上面的例子来说,上面bits数组的长度为13,那么总共可以存储(13*8)104个数字,分别是(0~103)

上面的代码并没有扩容方法,超出范围会报错,

使用bit数组来表示某些元素是否存在,比如8位电话号码.

缺点:

如果是比较特殊的数字,比如[1,100000000],那么就会浪费存储空间,比如这个就必须要(100000000>>3)个字节

针对上面的缺点,谷歌所实现的EWAHCompressedBitmap对bitmap存储空间做了一定的优化

相信的讲解:http://www.sohu.com/a/166661005_479559

问题实例

1、在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数
解法一:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^32 * 2 bit=1 GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。

解法二:也可采用与第1题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。”
2、给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
解法一:可以用位图/Bitmap的方法,申请512M的内存,一个bit位代表一个unsigned int值。读入40亿个数,设置相应的bit位,读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。

https://www.jianshu.com/p/6082a2f7df8e

https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/06.07.html

http://blog.51cto.com/zengzhaozheng/1404108

http://blog.csdn.net/h348592532/article/details/45362661

https://www.cnblogs.com/protected/p/6626447.html

http://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653191272&idx=1&sn=9bbcd172b611b455ebfc4b7fb9a6a55e&chksm=8c990eb2bbee87a486c55572a36c577a48df395e13e74314846d221cbcfd364d44c280250234&scene=21#wechat_redirect

海量数据处理-BitMap算法的更多相关文章

  1. (面试)Hash表算法十道海量数据处理面试题

    Hash表算法处理海量数据处理面试题 主要针对遇到的海量数据处理问题进行分析,参考互联网上的面试题及相关处理方法,归纳为三种问题 (1)数据量大,内存小情况处理方式(分而治之+Hash映射) (2)判 ...

  2. 海量数据处理算法—Bloom Filter

    海量数据处理算法—Bloom Filter 1. Bloom-Filter算法简介 Bloom-Filter,即布隆过滤器,1970年由Bloom中提出.它可以用于检索一个元素是否在一个集合中. Bl ...

  3. 从hadoop框架与MapReduce模式中谈海量数据处理

    http://blog.csdn.net/wind19/article/details/7716326 前言 几周前,当我最初听到,以致后来初次接触Hadoop与MapReduce这两个东西,我便稍显 ...

  4. 从Hadoop框架与MapReduce模式中谈海量数据处理(含淘宝技术架构) (转)

    转自:http://blog.csdn.net/v_july_v/article/details/6704077 从hadoop框架与MapReduce模式中谈海量数据处理 前言 几周前,当我最初听到 ...

  5. 从Hadoop骨架MapReduce在海量数据处理模式(包括淘宝技术架构)

    从hadoop框架与MapReduce模式中谈海量数据处理 前言 几周前,当我最初听到,以致后来初次接触Hadoop与MapReduce这两个东西,我便稍显兴奋,认为它们非常是神奇.而神奇的东西常能勾 ...

  6. july教你如何迅速秒杀掉:99%的海量数据处理面试题

    作者:July出处:结构之法算法之道blog 以下是原博客链接网址 http://blog.csdn.net/v_july_v/article/details/7382693 微软面试100题系列 h ...

  7. 海量数据处理面试题学习zz

    来吧骚年,看看海量数据处理方面的面试题吧. 原文:(Link, 其实引自这里 Link, 而这个又是 Link 的总结) 另外还有一个系列,挺好的:http://blog.csdn.net/v_jul ...

  8. 海量数据处理的 Top K 相关问题

    Top-k的最小堆解决方法 问题描述:有N(N>>10000)个整数,求出其中的前K个最大的数.(称作Top k或者Top 10) 问题分析:由于(1)输入的大量数据:(2)只要前K个,对 ...

  9. DBA_Oracle海量数据处理分析(方法论)

    2014-12-18 Created By BaoXinjian

随机推荐

  1. Python 字典 dict() 函数

    描述 Python 字典 dict() 函数用于创建一个新的字典,用法与 Pyhon 字典 update() 方法相似. 语法 dict() 函数函数语法: dict(key/value) 参数说明: ...

  2. SQL语句中的正则表达式

    正则表达式 REGEXP_LIKE执行正则表达式匹配 SELECT FIRST_NAME FROM EMPLOYEES WHERE REGEXP_LIKE(FIRST_NAME,'^al(an|yss ...

  3. 懂点PS技巧,你会减少很多痛苦

    UI设计 不像平面设计那样随性, 期间可以用点技巧来减少痛苦. 1. 设置网格线 保持像素完美 不在1:1分辨率下也能保持像素完美,可以通过创建网格线来避免虚边的出现. 编辑 > 首选项 > ...

  4. Can you answer these queries?---hdu4027

    题目链接 有n个数:当操作为1时求L到R的和: 当操作为0时更新L到R为原来的平方根: 不过如果仔细演算的话会发现一个2^64数的平方根开8次也就变成了 1,所以也更新不了多少次,所以可以每次更新到底 ...

  5. literallycanvas的简介

    LiterallyCanvas是什么 Literally Canvas是一个可扩展的开源(BSD许可)HTML5绘图组件,可以用于网页中插入画图板,类似于windows自带的画图板.可以用可视化工具绘 ...

  6. office 2016 install(office2016组件自定义安装激活程序) v5.9.3中文绿色版

    下载地址  http://www.ddooo.com/softdown/71741.htm#dltab office 2016 install是目前下载office2016和office2016组件最 ...

  7. Andrew Ng-ML-第十九章-应用举例:照片OCR(光学字符识别)

    1.问题描述与 OCR pipeline 图1.图像文字识别流水线 首先是输入图片->进行文字检测->字符分割->字符识别. 这些阶段分别需要1-5人这样子. 2.滑动窗口 主要讲滑 ...

  8. Centos 6.5安装OpenSSL

    方法一.直接安装 yum install openssl 方法二.下载源码编译安装 1.下载 wget https://www.openssl.org/source/openssl-1.0.2h.ta ...

  9. [LeetCode] 804. Unique Morse Code Words_Easy tag: Hash Table

    International Morse Code defines a standard encoding where each letter is mapped to a series of dots ...

  10. 机器学习理论基础学习12---MCMC

    作为一种随机采样方法,马尔科夫链蒙特卡罗(Markov Chain Monte Carlo,以下简称MCMC)在机器学习,深度学习以及自然语言处理等领域都有广泛的应用,是很多复杂算法求解的基础.比如分 ...