位图及有关海量数据处理

bitset
1.给40亿个不重复的无符号整数,没排过序,给一个无符号整数,如何快速判断一个数是否在这40亿个中
①.如果用排序加二分查找,40亿个数需要16g内存,内存开不出这么大连续空间
②.每个值映射一个比特位,需要开多少个比特位?并非40亿个,而是2^32个(42亿9千万),开空间开的不是数据个数,而是数据范围
0.5g
采用位图解决
数据是否在给定的整型数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,如果为0,代表不存在
模拟实现位图

template<size_t N>
class bitset{
	public:
	bitset(){
		bits.resize(N/32+1,0);
	}
	void set(size_t x){
		size_t i=x/32;
		size_t j=x%32;
		bits[i]|=(1<<j);
	}
	void reset(size_t x){
		size_t i=x/32;
		size_t j=x%32;
		bits[i]&=~(1<<j);
	}
	bool test(size_t x){
		size_t i=x/32;
		size_t j=x%32;
		return bits[i]&(1<<j);
	}
	private:
	vector<int>bits;
};

2.给定100亿个整数,设计算法找到只出现一次的整数
我们分三种情况讨论
出现0次 00
出现1次 0 1
出现两次及以上 1 0
我们考虑使用两个位图

template<size_t N>
class twobitset{
	public:
		bool set(size_t x){
			if(bs1.test(x)==false&&bs2.test(x)==false){
				bs1.set(x);
			}
			else if(bs1.test(x)==false&&bs2.test(y)==true){
				bs1.set(x);
				bs2.reset(x);
			}
		}
	private:
	  bitset<N>bs1;
	  bitset<N>bs2;
};

3.设计算法超出出现次数不超过2次的所有整数
出现0次 0 0
出现1次 0 1
出现2次 1 0
出现3次及以上1 1

template<size_t N>
class twobitset{
	public:
		bool set(size_t x){
			if(bs1.test(x)==false&&bs2.test(x)==false){
				bs1.set(x);
			}
			else if(bs1.test(x)==false&&bs2.test(x)==true){
				bs1.set(x);
				bs2.reset(x);
			}
			else if(bs1.test(x)==true&&bs2.test(x)==false){
			   bs2.set(x);
			   }
		}
	private:
	  bitset<N>bs1;
	  bitset<N>bs2;
};

4.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集
各自映射到一个位图,如果一个值在两个位图都存在,则是交集

template <size_t N> class bitset;

operator[]
在这里插入图片描述

#include<bitset>
#include<iostream>
using namespace std;
int main(){
	bitset<4>foo; //0000
	foo[1]=1;     //将第一位设为1  0010 
	foo[2]=foo[1]; //将第二位设为1 0110
	cout<<foo.test(2)<<endl;//因为已经将2这一位设为1,所以test(2)为true 
	cout<<foo[3]<<endl;//3这一位没被设置,故为0 
	cout<<foo<<endl; 
}

在这里插入图片描述
count(返回已经被set的个数)
在这里插入图片描述any
在这里插入图片描述
none
在这里插入图片描述
all
在这里插入图片描述
flip
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值