位图概念
基于哈希结构,在海量整型数据处理时,内存往往不够用,所以当只需要判断是否存在时,可以使用比特位来标记,一个整型数32个比特位,就可以标记32个数,如果有100亿个整数,就只需大约半个G的空间就可以处理,需要的空间大小和数据数量无关,和范围有关。
缺点:只能处理整型数
位图的建立
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct BitMap
{
size_t* _bits;
size_t _range;
}BitMap;
//1bit
void BitMapInit(BitMap* bm, size_t range)
{
assert(bm);
bm->_bits = (size_t*)malloc((sizeof(size_t)*range >> 5) + 1);
assert(bm);
memset(bm->_bits, 0, (sizeof(size_t)*range >> 5) + 1);
bm->_range = (sizeof(size_t)*range >> 5) + 1;
}
void BitMapSet(BitMap* bm, size_t x) //插入
{
assert(bm);
size_t frontin = x >> 5;
size_t secondin = x % 32;
bm->_bits[frontin] |= (1 << secondin);
}
void BitMapReset(BitMap* bm, size_t x)
{
assert(bm);
size_t frontin = x >> 5;
size_t secondin = x % 32;
bm->_bits[frontin] &= ~(1 << secondin);
}
// x存在返回0,不存在返回-1
int BitMapTest(BitMap* bm, size_t x)
{
assert(bm);
size_t frontin = x >> 5;
size_t secondin = x % 32;
if ((bm->_bits[frontin] & (1 << secondin)) == 0)
{
return -1;
}
else return 0;
}
void BitMapDestory(BitMap* bm)
{
assert(bm);
free(bm->_bits);
bm->_bits = NULL;
bm->_range = 0;
}
void BitMapHave(BitMap* bm1, BitMap* bm2)
{
assert(bm1);
assert(bm2);
size_t i = 0;
for (i = 0; i < bm1->_range; i++)
{
size_t tmp = bm1->_bits[i] & bm1->_bits[i];
if ( tmp != 0)
{
for (size_t j = 0; j < 36; j++)
{
if ((tmp&(1 << j)) != 0)
{
printf("%d ", i * 32 + j);
}
}
printf("\n");
}
}
}
//2bit
void BitMapInitTwo(BitMap* bm, size_t range)
{
assert(bm);
bm->_bits = (size_t*)malloc((sizeof(size_t)*range >> 4) + 1);
assert(bm);
memset(bm->_bits, 0, (sizeof(size_t)*range >> 4) + 1);
bm->_range = (sizeof(size_t)*range >> 4) + 1;
}
void BitMapSetTwo(BitMap* bm, size_t x) //插入
{
assert(bm);
size_t index = x >> 4;
size_t left = x % 16 * 2;
size_t right = x % 16 * 2+1;
if ((bm->_bits[index] & (1 << left))== 0
&& (bm->_bits[index] & (1 << right)) == 0) //00不存在
{
bm->_bits[index] |= (1 << right);
}
else if ((bm->_bits[index] & (1 << left)) == 0
&& (bm->_bits[index] & (1 << right)) != 0) //01存在一个
{
bm->_bits[index] |= (1 << left);
bm->_bits[index] &= ~(1 << right);
}
else if ((bm->_bits[index] & (1 << left)) != 0
&& (bm->_bits[index] & (1 << right)) == 0) //10存在两个
{
bm->_bits[index] |= (1 << right);
}
}
//不存在返回-1 一个返回1 两个返回 2 两个以上返回3
int BitMapTestTwo(BitMap* bm, size_t x)
{
assert(bm);
size_t index = x >> 4;
size_t left = x % 16 * 2;
size_t right = x % 16 * 2 + 1;
if ((bm->_bits[index] & (1 << left)) == 0
&& (bm->_bits[index] & (1 << right)) == 0) //00
{
return -1;
}
else if ((bm->_bits[index] & (1 << left)) == 0
&& (bm->_bits[index] & (1 << right)) != 0) //01
{
return 1;
}
else if ((bm->_bits[index] & (1 << left)) != 0
&& (bm->_bits[index] & (1 << right)) == 0) //10
{
return 2;
}
else if ((bm->_bits[index] & (1 << left)) != 0
&& (bm->_bits[index] & (1 << right)) != 0) //11
{
return 3;
}
}