位图的介绍和模拟实现
位图的介绍
经典面试题:
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。
常用方法有:
1.先排序,在利用二分查找
2.将数据放到unorder_set中,利用find进行查找,判断是否在这些数中
方法1
的时间复杂度:排序O(NlogN),二分查找O(logN)
方法2
的时间复杂度:O(N)
这2个方法都还可以,但是40亿个无符号整数会占用内存约16GB,空间消耗非常的大,所以上面的2种方法就不行了。
那么用位图来解决
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比
特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。
例如:
无符号整数是2^32个字节,也就是521MB的大小,空间消耗变得很小了。
位图概念
位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个
数据存不存在的。
位图的应用
- 快速查找某个数据是否在一个集合中
- 排序
- 求两个集合的交集、并集等
- 操作系统中磁盘块标记
位图使用
位图的定义
方式一:构造1个16位的位图,所有初始化位是0
bitset<16> foo;
方式二:构造1个16位的位图,根据所给值初始化前n位
bitset<16> bar(0xf);
方式三:构造1个16位的位图,根据字符串的0,1序列初始化
bitset<16> baz(string("1000001"));
打印出来的效果:
位图的成员函数
成员函数 | 功能 |
---|---|
set | 设置定位或所有位 |
reset | 清空指定位或所有位 |
filp | 反转指定位或所有位 |
test | 获取指定位的状态 |
count | 获取被设置位的个数 |
size | 获取可容纳的位的个数 |
any | 如果有任何一个位被设置则返回true |
none | 如果没有位被设置则返回true |
all | 如果所有位都被设置则返回true |
void Testbiset2()
{
bitset<16> baz;
baz.set(8);
baz.set(10);
cout << baz << endl;
baz.reset(