BitMap 分析

2018-05-29  本文已影响0人  巡_7272

BitMap 分析

引入

BitMap 从字面上是位图的意思,其实从内容翻译的角度来看,应当翻译成:基于位(Bit)的映射。

这里给出一个例子:

假如我们有一个无序的 int 数组,如 int arr[] = { 1, 4, 9, 3}; 这个数组占用内存 44 = 16 字节,一个这样的数据不可怕,但是假如有一亿个这样的数据,那么占用的内存 10^816/(102410241024) = 3.75G, 要想对这样巨大的数据进行查找,内存基本就会崩溃了。如果不是一次性的查找,那么就需要在硬盘上存盘,存盘就会带来 IO 的消耗,这样就会影响性能。

在这样的条件下,我们就有必要引入 BitMap 了。那么 BitMap 如何解决这个问题呢?

由于一个 Byte 占用 8 个 Bit,每一个 Bit 有 0 和 1 两个开关量,那么如果用一个二进制的 0 和 1 来代表该数是否存在,不是也能用来描述数组吗?

Byte[0] 1 0 1 0 0 1 1 0
7 6 5 4 3 2 1 0
Byte[1] 0 0 0 0 1 0 0 0
15 14 13 12 11 10 9 8

如果按照上图的表格进行表示数组,那么原来的 3.75 G 的数组就能通过 3.75/32 = 0.12 G 的数组来进行表示,首先节省了大量的空间,排序也更加简单了。这样的数据由于没有关联性,可以通过多线程进行读取,这样时间复杂度为 O(n/x),其中 n 为 全部数组的大小,x 为线程数量

应用

BitMap 不仅仅优越在占用空间小,由于针对 Bit 的逻辑运算也十分简单,使得其可以用于权限计算上

不过用到这个的时候,我们首先得知道如何对一个数据进行定位,即对于一个数据N,如何确定 index(组号)和 position(每组的位置号):

例如对于 14,14 超过了 Byte[0] 的范围,到达了 Byte[1] 的范围,那么我们对其进行定位可以用:

Index(N) = N / 8 = N >> 3 ;
Position(N) = N % 8 = N & 0x07 ;

添加数据 add(N)

如果想把一个数据 N 加入数组,按照前面所述,就只用把二进制的第 N 位置 1 即可,那么我们只用找到其组数和位置,进行位操作就可以了。

0 0 0 0 1 0 0 0
|
0 0 0 0 0 1 0 0
0 0 0 0 1 1 0 0
void add(int num)
{
  int index = num >> 3;         //  index = num / 8; 这两个是等价的
  int position = num & 0x07;    //  index = num % 8; 这两个是等价的
  bit[index] |= 1 << position;  // 相当于把 position 位置的数变成 1
}

删除数据 delete(N)

删除也是一样的,只需要对 1 进行左移操作,然后取反,对其进行与就可以了

void delete(int num)
{
  int index = num >> 3;             //  index = num / 8; 这两个是等价的
  int position = num & 0x07;        //  index = num % 8; 这两个是等价的
  bit[index] &= ~(1 << position);   // 相当于把 position 位置的数变成 0,后续位不变
}

确认数据 contain(N)

确认的话也是只用确认相应位是否为1 即可

char contain(int num)
{
  int index = num >> 3;         //  index = num / 8; 这两个是等价的
  int position = num & 0x07;    //  index = num % 8; 这两个是等价的
  return (bit[index] & 1 << position) != 0; // 相当于确认当前位是否为1
}

全部代码 C++:

public class BitMap {
    private byte[] bits;     //用于保存数据


    private int capacity;    //保存的数据量

    public BitMap(int capacity){
        this.capacity = capacity;

        //capacity 需要 capacity/8+1 个bit
        bits = new byte[(capacity >>3 )+1];
    }

    public void add(int num){
        int arrayIndex = num >> 3;
        int position = num & 0x07;
        bits[arrayIndex] |= 1 << position;
    }

    public boolean contain(int num){
        int arrayIndex = num >> 3;
        int position = num & 0x07;
        return (bits[arrayIndex] & (1 << position)) !=0;
    }

    public void clear(int num){
        int arrayIndex = num >> 3;
        int position = num & 0x07;
        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);
    }
}

上一篇 下一篇

猜你喜欢

热点阅读