哈希变形---位图

 
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);

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Victor.Chang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值