在许多公司的面试题中会考到这样的场景:给 40 亿个不重复无符号整数,如何快速判断一个数是否在这 40 亿数中。如果使用常规思路,每次查询暴力遍历 O(N) 太慢,排序加二分查找 O(NlogN)+O(logN),内存又不足以放下这些数据。
数据是否在给定的整型数据中,结果是在或不在,正好是两种状态,那么可以用一个二进制比特位来代表数据是否存在的信息,比特位为 1 代表存在,比特位为 0 代表不在。基于此,我们可以设计一个用比特位表示数据是否存在的数据结构——位图(BitMap)。
![图示:位图映射原理]
位图本质上是一个直接定址法的哈希表,每个整型值映射到一个比特位,位图提供控制这个比特位的相关接口,最主要的是 set、reset、test。
#include <vector>
#include <iostream>
namespace data_structures {
template<size_t N>
class BitMap {
public:
BitMap() {
// 一个 int 有 32 位,+1 为了向上取整,初始全用 0 填充
_bits.resize(N / 32 + 1, 0);
}
void set(size_t x) {
// i 找这个数在第几个 int
// j 找这个数在这个 int 中的第几个位
// 利用或运算将这一位设为 1,不改变其他位
size_t i = x / 32;
size_t j = x % 32;
_bits[i] |= (1 << j);
}
void reset(size_t x) {
// i 找这个数在第几个 int
// j 找这个数在这个 int 中的第几个位
// 利用且运算将这一位设为 0,不改变其他位
size_t i = x / 32;
size_t j = x % ;
_bits[i] &= ~( << j);
}
{
i = x / ;
j = x % ;
(_bits[i] & ( << j)) != ;
}
:
std::vector<> _bits;
};
}


