bitmap

1.bitmap可以用来存储用户与标签的对应关系,方便存储与查询

2.查询操作

//查询使用苹果手机的程序员用户
//程序员用户
00000001
//使用苹果手机用户
00000011
&
//得到查询结果
00000001

//查询男性或00后用户
//男性用户
00000011
|
//00后用户
00000100
//得到结果
00000111

//查询不是90后的用户
//90后用户
00000110
^
//全量用户(包含00,90)
00001110
//得到不是90后用户
00001000

bitmap实现原理

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

    .......
    
  如何判断int数字在tmp数组的哪个下标,这个其实可以通过直接除以32取整数部分,例如:整数8除以32取整等于0,那么8就在tmp[0]上。另外,我们如何知道了8在tmp[0]中的32个位中的哪个位,这种情况直接mod上32就ok,又如整数8,在tmp[0]中的第8 mod上32等于8,那么整数8就在tmp[0]中的第八个bit位(从右边数起)。
一个数怎么快速定位它的索引号,也就是说搞清楚byte[index]的index是多少,position是哪一位。举个例子吧,例如add(14)。14已经超出byte[0]的映射范围,在byte[1]范围之类。那么怎么快速定位它的索引呢。如果找到它的索引号,又怎么定位它的位置呢。Index(N)代表N的索引号,Position(N)代表N的所在的位置号。
  Index(N) = N/8 = N >> 3;
  Position(N) = N%8 = N & 0x07;
  

add操作


//得到第几行索引
let byteIndex = Math.floor(k / 16);

//得到第几列的索引
let bitIndex = k % 16;

//将1移动到索引的位置并修改该位置
this.blk[byteIndex] = this.blk[byteIndex] | (1 << bitIndex);

clear操作

  let byteIndex = Math.floor(k / 16);
        let bitIndex = k % 16;

this.blk[byteIndex] &= ~(1 << bitIndex)

contain操作

!((this.blk[byteIndex] & (1 << bitIndex)) === 0);

完整实现


class BitMap {
    constructor(n) {
        this.nbits = n;
        this.blk = new Array(Math.floor(n / 16) + 1);
        this.blk.fill(0);
    }

    get(k) {
        if( k > this.nbits) return false; 

        let byteIndex = Math.floor(k / 16);
        let bitIndex = k % 16;

        return !((this.blk[byteIndex] & (1 << bitIndex)) === 0);
    }

    set(k) {
        if( k > this.nbits) return; 

        let byteIndex = Math.floor(k / 16);
        let bitIndex = k % 16;

        this.blk[byteIndex] = this.blk[byteIndex] | (1 << bitIndex);

    }

    clear(k){
        if( k > this.nbits) return; 

        let byteIndex = Math.floor(k / 16);
        let bitIndex = k % 16;

        return !((this.blk[byteIndex] &= (~(1 << bitIndex))) === 0)
    }

}

let aBitMap = new BitMap(20);

aBitMap.set(1);
aBitMap.set(3);
aBitMap.set(5);
aBitMap.set(7);
aBitMap.set(9);
aBitMap.set(11);
aBitMap.set(13);
aBitMap.set(15);
aBitMap.set(17);
aBitMap.set(19);

console.log(aBitMap.clear(3))
console.log(aBitMap.get(3))
console.log(aBitMap.get(1))
console.log(aBitMap.get(5))
console.log(aBitMap.get(7))
console.log(aBitMap.get(9))

// console.log(aBitMap.get(3))
// for(let i = 0; i < 21; i++) {
//     console.log(aBitMap.get(i));
// }
posted @ 2019-10-27 18:59  pluscat  阅读(239)  评论(0)    收藏  举报