zoukankan      html  css  js  c++  java
  • 哈希变形---位图

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


  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/yongtaochang/p/13615365.html
Copyright © 2011-2022 走看看