目录
1、概念
位图,就是用每一位来存放某种状态,适用于海量数据【内存利用率高】,整数,数据无重复的场景。通常是用来判断某个数据存不存在的
说点好理解的,位图其实就是存在着一个映射关系【哈希】,原本存一个整数,需要4个字节,而在位图中,每一个比特位来标识一个数字,那此时,4个字节就有32个比特位,就是标识32个数字,当该数字出现过,该比特位为1,未出现过,该比特位为1
举例:
怎么确定位置:n/8确定区间,n%8确定该区间内所对应的下标
2、位图的简单使用
上代码:
import java.util.BitSet;
public class Test {
public static void main(String[] args) {
BitSet bitSet = new BitSet();
int[] arr = {3,6,8,25,34,45,37,58,26,47,2,5,1};
//将数组中的数据放入位图
for(int i = 0;i< arr.length;i++) {
bitSet.set(arr[i]);
}
System.out.println("是否存在25:"+ bitSet.get(25));
System.out.println("是否存在50: "+ bitSet.get(50));
}
}
结果:
3、自己实现位图:
大致实现:
public class MyBitSet {
public byte[] elem;
public int usedSize;
public MyBitSet() {
this.elem = new byte[1];//默认1个字节,8个比特位
}
public MyBitSet(int n) {
//为什么+1?假设n为12,那就是n/8等于1,还有4个没有给到,
// 原本分配1个字节,8个比特位不够,+1后分配2个字节,16个比特位,够够了
this.elem = new byte[n/8+1];
}
/**
* 设置某一位为1
* @param val
*/
public void set(int val) {
}
/**
* 判断当前位是不是1
* @param val
* @return
*/
public boolean get(int val) {
}
/**
* 设置当前位为0
* @param val
*/
public void reSet(int val) {
}
}
接下来将里面的三个函数进行具体的实现:
第一个,置1:
思路:
代码:
/**
* 设置某一位为1
* @param val
*/
public void set(int val) {
if(val<0) {
throw new IndexOutOfBoundsException();
}
int arrIndex = val/8;
int bitIndex = val%8;
elem[arrIndex] |= (1 << bitIndex);
usedSize++;
}
第二个,判断:
思路 :
代码:
/**
* 判断当前位是不是1
* @param val
* @return
*/
public boolean get(int val) {
if(val<0) {
throw new IndexOutOfBoundsException();
}
int arrIndex = val/8;
int bitIndex = val%8;
if((elem[arrIndex] & (1 << bitIndex)) != 0) {
return true;
}
return false;
}
第三个,置0:
思路:
代码:
/**
* 设置当前位为0
* @param val
*/
public void reSet(int val) {
if(val<0) {
throw new IndexOutOfBoundsException();
}
int arrIndex = val/8;
int bitIndex = val%8;
if(!get(val)) {
return;
}
elem[arrIndex] &= ~(1 << bitIndex);
usedSize--;
}
4、位图的应用
- 快速查找某个数据是否在一个集合中
- 排序 + 去重【按序取出即可】
- 求两个集合的交集、并集等
- 操作系统中磁盘块标记
好啦,这期就到这里了,我们下期再见!!!