极客时间-数据结构与算法之美-位图代码解析
作者:互联网
说明
位图概念, 不知道的可以自己搜索一下
如题, 里面有一段用java实现的位图代码
下面是我给重新命名之后的类
代码
记录一下自己的理解, 要用位, 去理解. 二进制, 而非十进制
代码仓库, 里面有详细的注释
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数据类型实现, 但是是否还要考虑到正负数等因素
## 为什么除以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;
按位或和按位与
标签:极客,0000,16,之美,char,charIndex,数组,长度,位图 来源: https://www.cnblogs.com/loseself/p/16138498.html