ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-04-13 07:31:06  阅读:202  来源: 互联网

标签:极客 0000 16 之美 char charIndex 数组 长度 位图


说明

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

如题, 里面有一段用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有