位运算操作符:或,与,异或,按位取反。
| | 两个中有一个是一则为一 |
---|---|
& | 两个都是一则为一 |
^ | 相同为零,不同为一 |
~ | 零变成一,一变成零 |
什么是位运算符:
位运算是直接对整型数据的二进制进行运算。
位图概念
所谓位图,就是用每一位比特位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用
来判断某个数据存不存在的。
位图的实现(通过上面的位运算操作符来实现位图的存储)
#include<iostream>
using namespace std;
#include<vector>class bitset
{
public:bitset(size_t x):_bit((x >> 5) + 1,0)//>>5 相当于除32 +1防止余数漏掉 将所有未初始化0 ,_nums(x){}//将which所对应的bit位设置为1void set(size_t which){if (which > _nums){return;}size_t index = which / 32;size_t pos = which % 32;_bit[index] |= (1 << pos);}//将which位置的bit位设置为0void reset(size_t which){if (which > _nums){return;}size_t index = which / 32;size_t pos = which % 32;_bit[index] &= ~(1 << pos);}//检测which位置是否存在bool check(size_t which){if (which > _nums){return false;}size_t index = which / 32;size_t pos = which % 32;return _bit[index] & (1 << pos);}//获取比特位的总个数size_t size()const{return _nums;}private:vector<int> _bit;size_t _nums;
};
代码测试:
int main()
{bitset a(32);a.set(16);a.set(2);a.set(31);a.set(8);return 0;
}
测试结果:
位图的应用
1. 快速查找某个数据是否在一个集合中
2. 排序 + 去重
3. 求两个集合的交集、并集等
4. 操作系统中磁盘块标记
面试题
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在
这40亿个数中。【腾讯】
1. 遍历,时间复杂度O(N)
2. 排序(O(NlogN)),利用二分查找: logN
3. 位图解决
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一
个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0
代表不存在。比如