/*
2-Bitmap_main.cpp
在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。
下面都假定为非负整数!!!
方案1:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,
共需内存2^32 * 2 bit=1 GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。
所描完事后,查看bitmap,把对应位是01的整数输出即可。
*/
#include<stdio.h>
#include<memory.h>
#include <cassert>
/*
每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义
用char数组存储2-Bitmap,不用考虑大小端内存的问题
2Bitmap a[40];
也就是说把2Bitmap看做一种数据类型,占两位。如2Bitmap a[8];共占8*2==16位,共2个字节。
但是我们不能直接用指针或下标操作来定位a[i]。故只能通过对char类型数据进行运算,来得到相应的a[i].
如:char b[10], b[0]对应a[3],a[2],a[1],a[0],
b[1]对应a[7],a[6],a[5],a[4],
...........................
b[9]对应a[39],a[38],a[37],a[36]
即b[j]对应:a[j*4+3],a[j*4+2],a[j*4+1],a{j*4]
反过来,a[i]对应b[i/4]的i%4 *2+1与i%4 *2 位
*/
const unsigned int N = 1000;
unsigned char b[N] = {0};//可以统计N*4个整数的情况
/*
此时 2Bitmap a[4*N];(当然不能在程序中这么写了)
a[i]为0,表示整数i没有出现过;为1表示整数i出现1次,为2表示整数i出现多次,为3表示未定义
*/
//************************************
// Method: get_value 获取a[i]即b[j]中的第i%4 *2+1与i%4 *2 位
// FullName: get_value
// Access: public
// Returns: unsigned int
// Qualifier:
// Parameter: size_t i
//************************************
unsigned int get_value(size_t i)
{
int index = i%4;
//获取b[j]的第index *2+1与index *2 位上的值所对应的整数值
return return (0x03<<(index*2))&b[i/4];
}
//************************************
// Method: set_value 设置a[i]为val,即设置b[j]的第index *2+1与index *2 位为val二进制的后两位
// FullName: set_value
// Access: public
// Returns: void
// Qualifier:
// Parameter: size_t i
// Parameter: unsigned char val
//************************************
void set_value(size_t i, unsigned char val)
{
assert(a<4);
int index = i%4;
// b[i/4] = b[i/4] (val<<(index*2));
b[i/4] = (b[i/4]&~((0x3<<(2*index))&0xff)) | (((val%4)<<(2*index))&0xff);
}
unsigned add_one(int idx)
{
if (get_value(idx)>=2) {
return 1;
}
else {
set_value(idx, get_value(idx)+1);
return 0;
}
}
大数据中2Bitmap的思想
最新推荐文章于 2020-06-09 11:00:45 发布