05 - 位图

位图

Step 1

  1. 位图的功能
    位图是拿每一个比特位来做图。
    位图的功能就是可以确定一个集合,如果给出数值的范围是确定的(给出确定的最大值),可以使用位图来记录是否存在的功能。
  2. 位图的好处
    极大的压缩空间。
    比如 0 - 1023,存储数字是否存在
    (1024b / 32b) = 32
    从而可以通过存储 32位整型数组,来记录1024个状态。
  3. 位图的实现
    见后面代码。

PS: 位运算的速度比算数运算速度快得多 (10倍以上)

位图的核心:

  1. 确定元素在数组的位置:bits[num/64] -> bits[num >> 6]
  2. 确定对应位 在对应元素的位置: (1L << (num % 64)) --> (1L << (num & 63)); 这个一定要是64,32等 2 的 n 次幂
  3. 最后就是 将对应位置 置为1,其余位不变(做或运算)
    或者 将对应位置置为0,其余为不变(做与运算,涉及取反操作)
package class05;

import java.util.HashSet;

public class BitMap {
    private long[] bits;

    public BitMap(int max) {
        max = ((max + 1) >> 6);
        if (((max + 1) & 63) != 0) {
            max += 1;
        }
        bits = new long[max];
    }

    public void add(int num) {
        bits[num >> 6] |= (1L << (num & 63));
    }

    public void delete(int num) {
        bits[num >> 6] &= ~(1L << (num & 63));
    }

    public boolean contains(int num) {
        return (bits[num >> 6] & (1L << (num & 63))) != 0;
    }
}

class Test{
    public static void main(String[] args) {
        System.out.println("测试开始!");
        int max = 10000;
        BitMap bitMap = new BitMap(max);
        HashSet<Integer> set = new HashSet<>();
        int testTime = 10000000;
        for (int i = 0; i < testTime; i++) {
            int num = (int) (Math.random() * (max + 1));
            double decide = Math.random();
            if (decide < 0.333) {
                bitMap.add(num);
                set.add(num);
            } else if (decide < 0.666) {
                bitMap.delete(num);
                set.remove(num);
            } else {
                if (bitMap.contains(num) != set.contains(num)) {
                    System.out.println("Oops!");
                    break;
                }
            }
        }
        for (int num = 0; num <= max; num++) {
            if (bitMap.contains(num) != set.contains(num)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("测试结束!");
    }
}

位运算实现加减乘除

  1. 加法
    异或运算就是无进位相加。
    进位信息 运算为 (a & b) << 1;
    (计算机底层不认加号的,底层只认逻辑门,也就是位运算。)

所以 a + b = (a ^ b) + ((a & b) << 1)
也就是 无进位相加 + 进位信息的结果

  1. 减法
    a-b --> a + (-b) --> 相反数怎么表示 —> b 的相反数 -b = ~b + 1; (也不是说完全的跟补码相同了,因为这里的取反是全部位包括符号位取反,从而取得相反数)

除法 特殊考虑 除数和被除数 是 系统最小值问题

!= 等于 ^ (异或)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值