位图法-bitmap

1. 简述

    昨天在看海量数据处理的题目,其中有一道题用的就是2-bitmap,今天学习一下bitmap,主要参考资料就是百度百科。

2. 定义

    bitmap是通过1个位表示一个状态,比如:int类型有2^32个数字,即4G个数字,那么每个数字一个状态,就是2^32个bit,即512 MB。

3. 应用

    · 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中
  首先,将这40亿个数字存储到bitmap中,然后对于给出的数,判断是否在bitmap中即可。
    · 使用位图法判断整形数组是否存在重复
      遍历数组,一个一个放入bitmap,并且检查其是否在bitmap中出现过,如果没出现放入,否则即为重复的元素。
    · 使用位图法进行整形数组排序
      首先遍历数组,得到数组的最大最小值,然后根据这个最大最小值来缩小bitmap的范围。这里需要注意对于int的负数,都要转化为unsigned int来处理,而且取位的时候,数字要减去最小值。
    · 在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数
      参考的一个方法是:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)。其实,这里可以使用两个普通的Bitmap,即第一个Bitmap存储的是整数是否出现,如果再次出现,则在第二个Bitmap中设置即可。这样的话,就可以使用简单的1-Bitmap了。

4. 实现   

#include  < iostream >
#include 
< cmath >
using   namespace  std;

#define   MAX  536870912  //  pow(2,29)
unsigned 
char  bitmap[(unsigned  int )MAX];

void  init() {
  memset(bitmap, 
0 , MAX * sizeof (unsigned  char )); 
}
void   set (unsigned  int  num) {
  bitmap[num
/ 8 |=  ( 128   >>  num % 8 );  //  pow(2,7)=128
}
bool  find(unsigned  int  num) {
  
return  bitmap[num / 8 &  ( 128   >>  num % 8 );
}
int  main() {
  init();
  
for ( int  i =- 10 ; i < 10 ; i ++ )
    
set (i);
  
for ( int  i =- 20 ; i < 20 ; i ++ )
    
if (find(i))
      cout 
<<   " i:  "   <<  i  <<  endl; 
  system(
" PAUSE " );
  
return   0 ;
}

    对于实现来说,百科上面的代码用的是int数组,不过char数组应该也是一样的,就是相当于数组长度大了点,差不多。对于unsigned int,主要是在除法和取余运算上的问题,因此要保证set和find函数中使用的一定是unsinged int类型,即要被强制转化的参数。

5. 备注

   普通bitmap的局限就是要求所有的状态都要放在内存里面,假设状态数量是2^64的话,那么内存肯定放不下,或者状态数量不变为2^32,但是内存要求10MB的话,就没法办了。另外好像有bitmap+mapreduce的方法,这个以后有机会再研究。

6. 参考

    十道海量数据处理面试题与十个方法大总结    http://blog.youkuaiyun.com/v_JULY_v/article/details/6279498
    位图法_百度百科    http://baike.baidu.com/view/6102616.html?tp=5_11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值