BitMap

  1. 类型基础
    计算机中最小单位的内存是bit,只可以表示0,1
    1Byte=8bit
    1int=4byte 32bit
    Float=4byte 32bit
    Long=8byte 64bit
    Char 2byte 16bit
  2. Int a= 1,这个1在计算机中是怎么存储的?
    0000 0000 0000 0000 0000 0000 0000 0001 toBinaryString(1)=1
    前面31位补0
    左移<<:1 << 2(位) = 2 乘 2 = 4 公式:2^n次幂 n表示移动的位数
    实例:
    数字1:0000 0000 0000 0000 0000 0000 0000 0001
    左移2:0000 0000 0000 0000 0000 0000 0000 0100
    右移>>:4 >> 2(位) = 4/2 乘2 = 1 公式:k/2^n次幂 n表示移动的位数,k表示需要移动的数字
    数字4:0000 0000 0000 0000 0000 0000 0000 0100
    右移2:0000 0000 0000 0000 0000 0000 0000 0001
    位与 &:同位上的两个数都是1则位1,否则为0
    位或 |:同为上的两个数只要有一个为1 则为1,否则为0
  3. 如何在3亿个整数(0~2亿)中判断某一个数是否存在?内存限制500M,一台机器。
    采用int来解决:
    1个int有32位bit;
    二进制表示: 0000 0000 0000 0000 0000 0000 0000 0000
    每个数是否存在就把0置为1;
    所以一个int数字就可以表示32个数字是否存在;
    那2亿个数字用int数组存下来所需要的空间:2亿4Byte/1024/1024 = 762M
    如果是bitMap:2亿/32
    4Byte/1024/1024=23M(因为我们最后还是会用int来表示bit),只不过我们开了int data[max/32+1],这里加一是因为整数相除会取整,如果除不下,需要多一个数组来存放;
    数组的大小data[2亿/32+1]
    计算再那个数组下:查找的数字/32 = 数组下标
    计算数组中的那个位置:查找的数字%32 = 数字所在数组的下标
  4. 位运算
    与或非异或:
    与:同时为1则为1;
    或:有一个为1则为1;
    非:取反;
    异或:相同为零,相异为1,即 0 ^ 1 = 1,0 ^ 0 =0,1 ^ 1 = 0;
    取反:~
    举例:
    1byte等于8位二进制,使用byte新增,查询,删除,下标为6的数据,二进制是:0100 0000换算成十进制等于64
    下面的计算:首先需要把1左移6为得到(下标从0开始):0100 0000
    新增:设置byte数据中的二进制位为1方式,或
    0000 0000
    0100 0000 或运算得到0100 0000
    查询:判断byte数据在二进制位是否为1,与
    0100 0000
    0100 0000 与运算等到 0100 0000
    如果等于0表示不存在,否则存在,因为1&1等于1,否则全是0
    删除:
    0100 0000
    0100 0000 异或运算得到0000 0000
    取模:
    8%8 = 8 & 8-1;
    8:0000 1000
    7:0000 0111
  5. 应用
    (1)数据判重
    (2)对没有重复的数据进行排序
  6. BitMap算法的缺点
    (1)数据不能重复
    (2)数据量少时相对于普通的hash没有优势
    (3)无法处理字符串:hash冲突
  7. BiMap算法的代码,
public class BitMap {

    int[] intData;
    int max;

    public BitMap(int max) {
        this.max = max;
        //max >> 往右移动3位 2*2*2=8,+1是因为取整的原因,需要把多余数部分的数据再开辟一个数组
        intData = new int[(max >> 5) + 1];
    }

    public void addInt(int number) {
        int array = number >> 5;
        int loc = number & 32-1;
        //接下来就是要把bit数组里面的 bisIndex这个下标的byte里面的 第loc 个bit位置为1
        //把1向左移动loc位,然后与data[loc]做或运算,就会把loc下标的0置为1
        intData[array] |= 1 << loc;
    }

    public boolean findInt(int number) {
        //除以8
        int array = number >> 5;
        int loc = number & 32-1;
        //如果原来的那个位置是0 那肯定就是0 只有那个位置是1 才行
        int flag = intData[array] & 1 << loc;
        if (flag == 0) return false;
        return true;
    }

    public void delInt(int number) {
        int array = number >> 5;
        int loc = number & 32-1;
        //删除,异或^或者使用~取反
        intData[array] = ~1 << loc;
    }

    public static void main(String[] args) {
        BitMap bitMap = new BitMap(200000001);    //10亿
        bitMap.addInt(2);
        bitMap.addInt(3);
        bitMap.addInt(65);
        bitMap.addInt(66);

        System.out.println(bitMap.findInt(3));
        System.out.println(bitMap.findInt(65));
        bitMap.delInt(65);
        System.out.println(bitMap.findInt(65));
    }
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值