目录
(1)位图引出
①面试题 : 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数 !

②位图解决

(2)基本概念
- //模拟实现位图
- template<size_t N>
- class bitset
- {
- public:
- //构造函数
- bitset();
-
- //设置位
- void set(size_t pos);
-
- //清空位
- void reset(size_t pos);
-
- //反转位
- void flip(size_t pos);
-
- //获取位的状态
- bool test(size_t pos);
-
- //获取可以容纳的位的个数
- size_t size();
-
- //获取被设置位的个数
- size_t count();
-
- //判断位图中是否有位被设置
- bool any();
-
- //判断位图中是否全部位都没有被设置
- bool none();
-
- //判断位图中是否全部位都被设置
- bool all();
-
- //打印函数
- void Print();
- private:
- vector<int> _bits; //位图
- };
(1)构造函数
- //构造函数
- bitset()
- {
- _bits.resize(N / 32 + 1, 0);
- }
(2)比特位操作设置
①set成员函数用于设置位
- void set(size_t pos) //把x映射的位标记成1
- {
- assert(pos < N);
- //算出x映射的位在第几个整数,
- //算出x映射的位在这个整数的第几位。
-
- int i = pos / 32;
- int j = pos % 32;
-
- _bits[i] |= (1 << j); //移位运算符的优先级低
- }
②reset成员函数用于清空位
- //清空位
- void reset(size_t pos)
- {
- assert(pos < N);
-
- //算出pos映射的位在第i个整数的第j个位
- int i = pos / 32;
- int j = pos % 32;
- _bits[i] &= (~(1 << j)); //将该位设置为0(不影响其他位)
- }
③flip成员函数用于反转位。
- //反转位
- void flip(size_t pos)
- {
- assert(pos < N);
-
- //算出pos映射的位在第i个整数的第j个位
- int i = pos / 32;
- int j = pos % 32;
- _bits[i] ^= (1 << j); //将该进行反转(不影响其他位)
- }
④test成员函数用于获取位的状态
- //获取位的状态
- bool test(size_t pos)
- {
- assert(pos < N);
-
- //算出pos映射的位在第i个整数的第j个位
- int i = pos / 32;
- int j = pos % 32;
-
- if (_bits[i] & (1 << j)) //该比特位被设置
- return true;
- else //该比特位未被设置
- return false;
- }
(3)统计相关
①size成员函数用于获取位图中可以容纳的位的个数
- //获取可以容纳的位的个数
- size_t size()
- {
- return N;
- }
②count成员函数用于获取位图中被设置的位的个数

- //获取被设置位的个数
- size_t count()
- {
- size_t count = 0;
- //将每个整数中1的个数累加起来
- for (auto e : _bits)
- {
- int num = e;
- //计算整数num中1的个数
- while (num)
- {
- num = num&(num - 1);
- count++;
- }
- }
- return count; //位图中1的个数,即被设置位的个数
- }
(4)打印函数
- //打印函数
- void Print()
- {
- int count = 0;
- size_t n = _bits.size();
- //先打印前n-1个整数
- for (size_t i = 0; i < n - 1; i++)
- {
- for (size_t j = 0; j < 32; j++)
- {
- if (_bits[i] & (1 << j)) //该位被设置
- cout << "1";
- else //该位未被设置
- cout << "0";
- count++;
- }
- }
-
- //再打印最后一个整数的前N%32位
- for (size_t j = 0; j < N % 32; j++)
- {
- if (_bits[n - 1] & (1 << j)) //该位被设置
- cout << "1";
- else //该位未被设置
- cout << "0";
- count++;
- }
- cout << " " << count << endl; //打印总共打印的位的个数
- }