一、位图
1. 概念与实现
在许多公司的面试题中会考到这样的场景:给 40 亿个不重复无符号整数,如何快速判断一个数是否在这 40 亿数中。 如果使用常规思路,每次查询暴力遍历 O(N) 太慢,排序 + 二分查找 O(NlogN)+O(logN),内存不足以放下这些数据。
数据是否在给定的整型数据中,结果是在或不在,正好是两种状态,那么可以用一个二进制比特位来代表数据是否存在的信息,比特位为 1 代表存在,比特位为 0 代表不在。那么,我们可以设计一个用比特位表示数据是否存在的数据结构——位图!

位图本质上是一个直接定址法的哈希表,每个整型值映射到一个比特位,位图提供控制这个比特位的相关接口,最主要的是 set、reset、test:
namespace lydly {
template<size_t N>// 模版参数表示有多少个数据
class Bitset {
public:
Bitset() {
// 一个 int 有 32 位,+1 为了向上取整,初始全用 0 填充
_bits.resize(N / 32 + 1, 0);
}
void set(size_t x) // 将一个数的映射位设为 1
{
// i 找这个数在第几个 int
// j 找这个数在这个 int 中的第几个位
// 利用或运算将这一位设为 1,不改变其他位
size_t i = x / 32;
size_t j = x % 32;
_bits[i] |= (1 << j);
}
void reset(size_t x) // 将一个数的映射位设为 0
{
// i 找这个数在第几个 int
// j 找这个数在这个 int 中的第几个位
// 利用且运算将这一位设为 0,不改变其他位
i = x / ;
j = x % ;
_bits[i] &= ~( << j);
}
{
i = x / ;
j = x % ;
_bits[i] & ( << j);
}
:
std::vector<> _bits;
};
}








