位图:位图就是bitmap的缩写。所谓bitmap,就是用每一位来存放某种状态,适用于海量数据,但数据状态又不是很多的情况。通常是用来判断某个数据是否存在。
总之,位图就是一个用每一位的0,1来表示一个数的状态。
如下图所示:
实际应用
【腾讯】给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。
//位图
//1byte = 8bit;
//1024byte = 1kb;
//1024kb = 1mb;
//1024mb = 1gb;
typedef struct BitMap
{
size_t *_bits;
size_t _range;//范围
}BitMap;
void BitMapInit(BitMap* bm, size_t range);
void BitMapSet(BitMap* bm, size_t x);
void BitMapReSet(BitMap* bm, size_t x);
int BitMapTest(BitMap* bm, size_t x);
//x存在返回0,不存在返回-1;
void BitMapInit(BitMap* bm, size_t range)
{
assert(bm);
bm->_range = range;
bm->_bits = (size_t*)malloc((sizeof(size_t))*(bm->_range >> 5) + 1);//相当于除以32bit
memset(bm->_bits,0,(sizeof(size_t))*(bm->_range >> 5) + 1);
}
void BitMapSet(BitMap* bm, size_t x)
{
assert(bm);
size_t index = x >> 5;//找位置
size_t num = x % 32;
bm->_bits[index] |= (1 << num);//1|0=1
}
void BitMapReSet(BitMap* bm, size_t x)
{
size_t index = x >> 5;//找位置
size_t num = x % 32;
bm->_bits[index] &= (~(1 << num));//1&0=0; 1~0=1;
}
int BitMapTest(BitMap* bm, size_t x)
{
size_t index = x >> 5;//找位置
size_t num = x % 32;
if (((bm->_bits[index]) & (1 << num)) != 0)
{
return 0;
}
else
return -1;
}
void TestBitMap()
{
BitMap bm;
BitMapInit(&bm, -1);//也可写为32个2相乘不推荐,程序中不可写为2^5;
BitMapSet(&bm, 1);
BitMapSet(&bm, 8);
BitMapSet(&bm, 10000);
BitMapSet(&bm, 1000111111);
printf("10000 ? %d\n", BitMapTest(&bm, 10000));
printf("1000111111? %d\n", BitMapTest(&bm, 1000111111));
printf("8 ? %d\n", BitMapTest(&bm, 8));
printf("1 ? %d\n", BitMapTest(&bm, 1));
}
执行结果如图