哈希变形---位图

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("
");
	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 
",BitMapNum(&bm,2));
	printf("10?  %d 
",BitMapNum(&bm,10));
	printf("66?  %d 
",BitMapNum(&bm,66));
	BitMapFind(&bm);
	BitMapReset(&bm,66);
	BitMapReset(&bm,305);
	BitMapReset(&bm,10);
	printf("66?  %d 
",BitMapNum(&bm,66));
	printf("305?  %d 
",BitMapNum(&bm,66));
	printf("10?  %d 
",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);

}


原文地址:https://www.cnblogs.com/yongtaochang/p/13615365.html