import java.util.ArrayList;
import java.util.Date;
import java.util.List;
class BitSet{
// 常数表示存多大的数
static final int N = 10000000;
// 数组存储
int[] bitMap;
// 初始化
public BitSet() {
bitMap = new int[N/32+1];
}
//添加一个数字
public void add(int value) {
int index = value/32; // 位于数组bitmap中的index位置
int offset = value%32-1; //这个int中的bit位置,offset是1移动多少位置
// 放入
/*
1 << offset:
这部分代码使用左移操作符(<<)将数字1向左移动offset位。
例如,如果offset是3,1 << 3的结果是0000 1000(二进制),即8。
bitMap[index]:
bitMap[index]表示当前索引位置的整数值。这个值是一个32位的二进制数。
|(按位或操作符):
|操作符用于将两个操作数的每一位进行比较,只要其中一个操作数的位为1,结果的对应位就为1。
这意味着如果bitMap[index]的某一位已经是1,结果还是1;如果是0,则会被设置为1。
*/
bitMap[index] = bitMap[index] | 1<<offset;
}
// 判断一个数字是否存在
public boolean isExist(int value) {
int index = value/32;
int offset = value%32-1;
/*
0x01(即二进制的0000 0001)
这段代码的整体逻辑是:
检查在位图bitMap的index位置,经过offset位的右移后,最低位是否为1。
如果是1,说明该值存在于位集合中,flag被设置为true;否则为false。
*/
boolean flag = ((bitMap[index]>>offset)&0x01)==0x01?true:false;
return flag;
}
// 如何根据bitMap恢复原始数据
public List<Integer> reverseDigit() {
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<bitMap.length;i++) {
int temp = bitMap[i];
for(int j=0;j<32;j++) {
/*
整体逻辑是:
检查temp的第j位是否为1。
如果是1,flag被设置为true;如果是0,flag被设置为false。
*/
boolean flag = ((temp>>j)&0x01)==0x01?true:false;
if(flag) {
int data = i*32+j+1;
list.add(data);
}
}
}
return list;
}
}
衍生一个2bit的map 可以保存一个数字的四种状态
import java.util.ArrayList;
import java.util.List;
class BitMap2bit {
// 常数表示存多大的数
static final int N = 10000000;
// 数组存储
int[] bitMap;
// 初始化
public BitMap2bit() {
bitMap = new int[N / 16 + 1]; // 每个数字占用2位,因此需要更多的空间
}
// 添加一个数字,状态可以是0、1、2或3
public void add(int value, int state) {
int index = value / 16; // 位于数组bitmap中的index位置
int offset = (value % 16) * 2; // 每个数字占用2位,计算偏移
// 先清除这个位置的2位,然后设置新状态
bitMap[index] = (bitMap[index] & ~(0b11 << offset)) | (state << offset);
}
// 判断一个数字是否存在
public int getState(int value) {
int index = value / 16;
int offset = (value % 16) * 2;
// 提取状态的2位
return (bitMap[index] >> offset) & 0b11; // 返回0、1、2或3
}
// 如何根据bitMap恢复原始数据
public List<int[]> reverseDigit() {
ArrayList<int[]> list = new ArrayList<>();
for (int i = 0; i < bitMap.length; i++) {
int temp = bitMap[i];
for (int j = 0; j < 16; j++) { // 16因为每个数字占用2位
int state = (temp >> (j * 2)) & 0b11; // 提取状态
if (state != 0) { // 只记录状态不为0的数字
int data = i * 16 + j; // 计算原始数字
list.add(new int[]{data, state}); // 返回数字和状态
}
}
}
return list;
}
}