BitMap
位图(bitmap)是一种非常常用的结构,在索引,数据压缩等方面有广泛应用。位图是通过将数组下标与应用中的一些值关联映射,数组中该下标所指定的位置上的元素可以用来标识应用中值的情况(是否存在或者数目 或者计数等),位图数组中每个元素在内存中占用1位,所以可以节省存储空间。位图是一种非常简洁快速的数据结构,它能同时使存储空间和速度最优化。如可用一个10位长的字符串来表示一个所有元素都小于10的简单的非负整数集合,例如,可以用如下字符串表示集合{1,2,4,5,8} ,对应位置数字存在标记为1,否则标记为0。
这里BitMap指的是把数据存放在一个以bit为单位的数据结构里。
每位都只有0和1两个值。为0的时候,证明值不存在,为1的时候说明存在。
举例来说:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
这是24位,也就是24bit, 同时8bit为1个字节。这里的空间也就是3个字节。
这个时候假如我们要存放2 4 6 8 9 10 17 19 21这些数字到我们的BitMap里,我们只需把对应的位设置为1就可以了。
[0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0]
数据结构
假如,我们要存储的数据范围为0-15,这里的数据是16bit:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
数据为[5, 1, 7, 15, 0, 4, 6, 10]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[1 0 0 0 0 1 0 0 1 1 1 1 0 0 1 1]
例如:
申请一个int型的内存空间,则有4Byte,32bit。输入 4, 2, 1, 3时:
输入4:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
输入2:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0]
输入1:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0]
输入3:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0]
map映射表
假设需要排序或者查找的总数N=10000000,那么我们需要申请的内存空间为 int a[N/32 + 1].其中a[0]在内存中占32位,依此类推:
bitmap表为:
a[0] ——> 0 - 31
a[1] ——> 32 - 63
a[2] ——> 64 - 95
a[3] ——> 96 - 127
……
位移转换
- 求十进制数0-N对应的在数组a中的下标
公式:index = N / 32即可,index即为对应的数组下标。例如N = 76, 则index = 76 / 32 = 2,因此76在a[2]中。 - 求十进制数0-N对应的bit位
bit = N % 32即可,例如 N = 76, bit = 76 % 32 = 12 - 利用移位0-31使得对应的32bit位为1
代码实现
##include <iostream>
#include <vector>
using namespace std;
class BitMap
{
public:
BitMap( int range )
{
//开辟空间
this->m_bits.resize(range / 32 + 1);
}
void set( int data )
{
int index = data / 32; //数组索引即区间
int temp = data % 32; //具体位置索引
this->m_bits[index] |= ( 1 << temp); //左移4位置为1
}
void reset( int data)
{
int index = data / 32;
int temp = data % 32;
this->m_bits[index] &= ~( 1 << temp ); //取反
}
bool test(int data)
{
int index = data / 32;
int temp = data % 32;
if( this->m_bits[index]&( 1 << temp))
{
return true;
}
else
{
return false;
}
}
private:
vector<int> m_bits;
};
void testBitMap()
{
BitMap bitmap_1(-1);
BitMap bitmap_2(31);
bitmap_2.set(16);
bitmap_2.set(1);
cout<< bitmap_2.test(16) << endl;
bitmap_2.reset(16);
cout<< bitmap_2.test(16) << endl;
}
int main()
{
testBitMap();
}