大数据

位图-BitMap

2018-08-28  本文已影响0人  執著我們的執著

BitMap

字面意思解释为位图,准确翻译为基于位的映射

What is 基于位的映射?

举个例子,立马了解BitMap的基本思想

基于上述基本思想,Bit-map算法在处理大量数据排序、查询以及去重;以及在用户群做交集和并集运算的时候也有极大的便利。



1. BitMap的应用
1.1 快速的排序

假设要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复),就可以采用Bit-map的方法来达到排序的目的。要表示 8个数,只需要8Bit(1 Bytes);
首先我们开辟1 Byte的空间,将这些空间的所有Bit位都置为0


然后遍历这5个元素,不考虑大小端,默认大端存储,将对应元素的对应位置为1,比如第一个元素为4,则将开辟的空间的第5位置为1(因为是从0开始的)

最后再遍历一遍Bit区域,将该位是1的位的编号输出(2,3,4,5,7),这样就达到了排序的目的,时间复杂度O(n)
利用BitMap实现的排序

//定义每个Byte中有8个Bit位
#include <memory.h>
#define BYTESIZE 8
void SetBit(char *p, int posi)
{
    for(int i=0; i < (posi/BYTESIZE); i++)
    {
        p++;
    }
 
    *p = *p|(0x01<<(posi%BYTESIZE));//将该Bit位赋值1
    return;
}
 
void BitMapSortDemo()
{
    //为了简单起见,我们不考虑负数
    int num[] = {3,5,2,10,6,12,8,14,9};
 
    //BufferLen这个值是根据待排序的数据中最大值确定的
    //待排序中的最大值是14,因此只需要2个Bytes(16个Bit)
    //就可以了。
    const int BufferLen = 2;
    char *pBuffer = new char[BufferLen];
 
    //要将所有的Bit位置为0,否则结果不可预知。
    memset(pBuffer,0,BufferLen);
    for(int i=0;i<9;i++)
    {
        //首先将相应Bit位上置为1
        SetBit(pBuffer,num[i]);
    }
 
    //输出排序结果
    for(int i=0;i<BufferLen;i++)//每次处理一个字节(Byte)
    {
        for(int j=0;j<BYTESIZE;j++)//处理该字节中的每个Bit位
        {
            //判断该位上是否是1,进行输出,这里的判断比较笨。
            //首先得到该第j位的掩码(0x01<<j),将内存区中的
            //位和此掩码作与操作。最后判断掩码是否和处理后的
            //结果相同
            if((*pBuffer&(0x01<<j)) == (0x01<<j))
            {
                printf("%d ",i*BYTESIZE + j);
            }
        }
        pBuffer++;
    }
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    BitMapSortDemo();
    return 0;
}
1.2 快速去重
1.3 快速查询

        同样,我们利用Bit-map也可以进行快速查询,这种情况下对于一个数字只需要一个bit位就可以了,0表示不存在,1表示存在。假设上述的题目改为,如何快速判断一个数字是够存在于上述的2.5亿个数字集合中。
  同之前一样,首先我们先对所有的数字进行一次遍历,然后将相应的转态位改为1。遍历完以后就是查询,由于我们的Bit-map采取的是连续存储(整型数组形式,一个数组元素对应32bits),我们实际上是采用了一种分桶的思想。一个数组元素可以存储32个状态位,那将待查询的数字除以32,定位到对应的数组元素(桶),然后再求余(%32),就可以定位到相应的状态位。如果为1,则代表改数字存在;否则,该数字不存在。



2. 扩展

3. 实战
  • 适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下
  • 基本原理及要点:使用bit数组来表示某些元素是否存在,比如8位电话号码
  • 扩展:bloom filter可以看做是对bit-map的扩展

(1) 已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数。

(2) 2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。



总结

使用Bit-map的思想,我们可以将存储空间进行压缩,而且可以对数字进行快速排序、去重和查询的操作。Bloom Fliter是Bit-map思想的一种扩展,它可以在允许低错误率的场景下,大大地进行空间压缩,是一种拿错误率换取空间的数据结构。

引用

参考 1
参考 2
参考 3
参考 4: july
参考 5
参考 6

上一篇 下一篇

猜你喜欢

热点阅读