BitMap 分析

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);
    }
}

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351