编程语言
首页 > 编程语言> > 极客时间-数据结构与算法之美-位图代码解析

极客时间-数据结构与算法之美-位图代码解析

作者:互联网

说明

位图概念, 不知道的可以自己搜索一下

如题, 里面有一段用java实现的位图代码

image

下面是我给重新命名之后的类

image


代码

记录一下自己的理解, 要用位, 去理解. 二进制, 而非十进制
代码仓库, 里面有详细的注释
https://github.com/loseself/demo-algorithm/blob/master/src/test/java/bigmap/BitMapWithComments.java



为什么使用char实现位数组

位, bit, 二进制的一位, 值是0或1

长度是位的长度, 值是0, 1
使用char实现, Java 中 char 类型是 2 个字节, 占 16bit, 所以1个长度的char数组, 是16个长度的位数组
至于char没有负数形式, 是不是使用它实现的原因之一, 则需要认证

/**
 * char实现的位数组
 * char是2个字节, 16位
 * 假如: 数组的长度是2, 2个char, 则位数组是32个长度, 32位
 */
private final char[] bitArray;

/**
 * 位数组的长度
 * 假如你声明, 长度为16, 则只需要声明长度为1的char数组即可
 */
private final int bitArrayLength;

/**
 * 构造函数
 *
 * @param bitArrayLength 位数组长度
 */
public BitMapWithComments(int bitArrayLength) {
    // 位数组长度赋值
    this.bitArrayLength = bitArrayLength;

    // 用char实现, 一个char, 16位, 所以以16位为一个单位
    // + 1 的意思是, 至少一个长度的char数组, 也就是至少16位
    this.bitArray = new char[bitArrayLength / 16 + 1];
}

你也可以使用其他java数据类型实现, 但是是否还要考虑到正负数等因素

image


## 为什么除以16和取余16

除法, 把该数放到哪个char上
取余, 把该数放到那个位的位置上

// 除法
// 该k放到那个char当中
// 假如k是0~15, 则放到第一个char中
// 假如k=16, 则放在第二个char中, charIndex=1
// charIndex从0开始
// 所以说明这个k, 以"位"的长度来衡量
int charIndex = k / 16;

// 取余
// 假设位数组长度为32
// 该k, 在16位中的位置, 从0开始
// 如果k=17, 则在16位的第1位, 如果k=18, 则在16位的第2位 
int bitIndex = k % 16;

为什么要1左移位数

标记该数, 把该数在16位上的位置变为1

// 假设k=17, charIndex=1, bitIndex=1, 则1的二进制0001左移1位, i为0010, 十进制为2
// 为什么要左移, 首先代码走到这里, 说明该16个位上肯定会有1出现
// 现在bitIndex为1, 则在第1位
// 说明, 该k, 在该16位的第一位标记为1, 0000 0000 0000 0010
int i = 1 << bitIndex;

set的时候为什么要按位或

保留位上已经是1的值

// 赋值
// | 按位或, 相对应位只要有一个为1,其值为1
// A|=B ---> A = A | B
// 为什么使用按位或, 假如在同一个char的下标, charIndex相同
// bitIndex相同时, 根据按位或的计算公式, 则可保留该位上的1
// bitIndex不相同时, 则保留之前位的1, 其他位仍可变为1

// 第一次进来, k = 17, charIndex=1, bitIndex=1
// char 默认为 0
// 0000 0000 0000 0000 | 0000 0000 0000 0010 = 0000 0000 0000 0010
// 假如第二次进来, k = 18, charIndex=1, bitIndex=2
// 之前的 0000 0000 0000 0010 | 0000 0000 0000 0100 = 0000 0000 0000 0110
bitArray[charIndex] |= i;

get的时候为什么要按位与

判断是否该位上已经是1

// 转换成二进制, 看该k在哪个位上是1
int i = 1 << bitIndex;

// & 按位与, 如果相对应位都是1,则结果为1,否则为0
// 通过按位与运算规则, 说明如果计算结果为1, 则数组中就已存在
// 0000 0000 0000 0010 & 0000 0000 0000 0010 = 0000 0000 0000 0010
// 0000 0000 0000 0010 --> 2 --> 2 != 0
return (bitArray[charIndex] & i) != 0;

按位或和按位与

image

标签:极客,0000,16,之美,char,charIndex,数组,长度,位图
来源: https://www.cnblogs.com/loseself/p/16138498.html