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


  • 相关阅读:
    [Linux]常用命令之【tar/zip/unzip/gzip/gunzip】
    [Git]解决: error: unable to create file src/main/webapp/xxxxxx/xxxx: Filename too long
    [Git]解决:error: The following untracked working tree files would be removed by checkout:
    [Linux]命令行分类
    [数据库/MYSQL]#解决缺陷#设置Unique索引时:"[Err] 1071
    [Java EE]辨析: POJO(PO / DTO / VO) | BO/DO | DAO
    [Java]遍历枚举类型为List
    【Vue】在Vue项目中调试Vue源码——修改Vue项目引入的vue文件
    【Vue】Vue源码解读之Component组件注册
    【Vue】驼峰命名法和短横线命名法的转换以及Vue源码中对驼峰式和大写式查找的支持
  • 原文地址:https://www.cnblogs.com/yongtaochang/p/13615365.html
Copyright © 2011-2022 走看看