BitMap
我们有 1 千万个整数,范围在 1 到 1 亿之间。如何快速查找某个整数是否存在?
我们可借助hash,或者开1亿的bool数组(存在为true否则false),但是这些做法都耗费内存。
BitMap通过位运算,只需一个二进制位(bit)来表示true(1)或者false(0),相比bool数组内存缩小8倍
伪代码:
class BitMap {
public:
//BitMap数组,总共需要nbits位
int *bytes = null;
int nbits = 0;
BitMap(int nbits) {
this->nbits = nbits;
this->bytes = new int[nbits/32+1]; //一个int型4字节,1字节8位,共32位
}
//添加整数k到BitMap数组
void set(int k) {
if (k > nbits) return;
int byteIndex = k / 32;
int bitIndex = k % 32;
bytes[byteIndex] |= (1 << bitIndex);
}
//查询BitMap数组中是否存在整数k
bool get(int k) {
if (k > nbits) return false;
int byteIndex = k / 32;
int bitIndex = k % 32;
return (bytes[byteIndex] & (1 << bitIndex)) != 0;
}
}
Bloom过滤器
上面范围只有1~1亿,我们用BitMap仅需要100000000/8/1024/1024=12.5MB
如果这一千万个数范围在1到1万亿间呢?那就至少需要12.5 × 10000=125000MB,也就是125G内存了
布隆过滤器减少位图占用内存,通过多次hash到位图的不同位,来添加或判定整数是否存在(hash到的所有位同时为1说明整数存在)。
它适用于允许小概率误判的大规模判重场景,比如根据黑名单判断垃圾短信号码