什么叫位图?
位图,就是用一块内存区域的每一个比特位表示一个对象的数据结构。
叫做 bitmap 或者 bitplane。
面试题
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快
速判断一个数是否在这40亿个数中。 【腾讯】
我们来分析一下这个问题:40亿个整数想要放到内存中势必需要很大很大的空间,更何况要对40亿个数据进行查找,那时间复杂度将会很大。
基于此,我们用位图的方法的来存储数据出现的次数,最后查找即可。
用int来举例,一个int4个字节,所以有32个比特位。
这样一个int便可以占32个数字。
所以这样子会大大的节省空间。
实现位图
#pragma once
//位图
#include <vector>
#include <iostream>
using namespace std;
class BitMap
{
public:
BitMap()
{}
BitMap(size_t size)
{
//因为是int 4个字节 32比特位
//所以移5位,刚好32个比特位
_table.resize((size >> 5) + 1);
}
void Set(int data)
{
//计算此数字在第几个字节处(data / 32),第几位(data % 32)
//然后把第几位置为1 如果已经是1就不变
size_t byteNo = data >> 5;
size_t bitNo = data % 32;
_table[byteNo] |= (1 << bitNo);
}
//恢复为原来的
void ReSet(int data)
{
size_t byteNo = data >> 5;
size_t bitNo = data % 32;
//这一位与0
_table[byteNo] &= ~(1 << bitNo);
}
//检查数字是否在其中
bool Check(int data)
{
size_t byteNo = data >> 5;
size_t bitNo = data % 32;
//如果这一位左移 按位与 如果此时不为0 则此数字存在
if ((1 << bitNo)&_table[byteNo])
return true;
return false;
}
private:
vector<int> _table;
};
void Test()
{
BitMap bp(1);
bp.Set(0);
bp.Set(1);
bp.Set(2);
bp.Set(3);
bp.Set(4);
bp.Set(5);
bp.Set(6);
bp.ReSet(3);
cout << bp.Check(3);
cout << bp.Check(7);
}