1.给定100亿个整数,设计算法找到只出现一次的整数 2.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集 3.1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
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) ;
//返回x出现的次数
int BitMapNum(BitMap* bm, size_t x);
int BitMapFind(BitMap* bm) ;
void BitMapInter(BitMap* bm1,BitMap* bm2);
///
void BitMapInit(BitMap* bm, size_t range) {
assert(bm);
bm->_range=(range>>4)+1;
bm->_bits=(size_t*)malloc(sizeof(size_t)*((range>>4)+1));
memset(bm->_bits,0,sizeof(size_t)*((range>>4)+1));
}
void BitMapSet(BitMap* bm, size_t x) {
size_t index,num;
index=x>>4;
num=(x%32)*2;
if((bm->_bits[index]&(3<<num))==0)//该位置为00,让它置为01
bm->_bits[index]+=(1<<num);
else if(((bm->_bits[index]&(3<<num))>>num)==1) //该位置为01,置为10
bm->_bits[index]+=(1<<num);
else if(((bm->_bits[index]&(3<<num))>>num)==2) //该位置为10,置为11
bm->_bits[index]+=(1<<num);
else //该位置为11,不做修改
return;
}
void BitMapReset(BitMap* bm, size_t x) {
size_t index,num;
index=x>>4;
num=(x%32)*2;
if(((bm->_bits[index]&(3<<num))>>num)>0) //该位置大于0,置0
bm->_bits[index]&=(~(3<<num));
}
// 返回x出现的次数
int BitMapNum(BitMap* bm, size_t x){
size_t index,num;
index=x>>4;
num=(x%32)*2;
if((bm->_bits[index]&(3<<num))==0) //该位置为00,
return 0;
else if(((bm->_bits[index]&(3<<num))>>num)==1) //该位置为01
return 1;
else if(((bm->_bits[index]&(3<<num))>>num)==2) //该位置为10
return 2;
else //该位置为11, 返回3表示多次
return 3;
}
1,2问题可归为一类,每一个整数由2位来表示状态 00为空,01为一个,10为2个,11为多个;
根据条件判断,来输出相应的值
//找一次与不超过两次方法基本类似
int BitMapFind(BitMap* bm){
size_t i,j,cur;
for(i=0;i<bm->_range;i++){
cur=bm->_bits[i];
for(j=0;j<32;j+=2){
//条件判断 1 一次, 2 两次, 3 多次
if((cur&(3<<j))>>j>0&&(cur&(3<<j))>>j<3)
printf("%d ",i*16+j/2);
}
}
printf("\n");
return 0;
}
问题2,求两位图相交,将他们相交后的数组元素赋给其中一个
//打印两个相交的位图
void BitMapInter(BitMap bm1,BitMap bm2){
size_t i,n;
assert(bm1&&bm2);
n= bm1._range<bm2._range?bm1._range:bm2._range;
for(i=0;i<n>>4;i++){
bm1._bits[i]=(bm1._bits[i])&(bm2._bits[i]);
}
BitMapFind(&bm1);
}
void BitmapTest1(){
BitMap bm,bm2;
BitMapInit(&bm,1000000);
BitMapInit(&bm2,500000);
BitMapSet(&bm,2);
BitMapSet(&bm,10);
BitMapSet(&bm,10);
BitMapSet(&bm,80);
BitMapSet(&bm,75);
BitMapSet(&bm,37);
BitMapSet(&bm,18);
BitMapSet(&bm,66);
BitMapSet(&bm,66);
BitMapSet(&bm,66);
BitMapSet(&bm,305);
printf("2 ? %d \n",BitMapNum(&bm,2));
printf("10? %d \n",BitMapNum(&bm,10));
printf("66? %d \n",BitMapNum(&bm,66));
BitMapFind(&bm);
BitMapReset(&bm,66);
BitMapReset(&bm,305);
BitMapReset(&bm,10);
printf("66? %d \n",BitMapNum(&bm,66));
printf("305? %d \n",BitMapNum(&bm,66));
printf("10? %d \n",BitMapNum(&bm,10));
printf("bm1:");
BitMapFind(&bm);
BitMapSet(&bm2,1);
BitMapSet(&bm2,2);
BitMapSet(&bm2,37);
BitMapSet(&bm2,80);
BitMapSet(&bm2,200);
BitMapSet(&bm2,160);
printf("bm2:");
BitMapFind(&bm2);
printf("bm1&bm2:");
BitMapInter(bm,bm2);
}