位图的介绍及实现

位图的介绍

在一般的查找中,通常想的是用数组或者STL中的容器存储数据,当查找某个数据是否存在的时候,可以通过一系列查找算法对容器内的数据进行查找。但是如果数据海量,上亿级甚至更高的时候,这样的方法就显得效率很低了,先不说数据是否超范围,单单循环遍历就需要很久,这给用户的体验是非常差的,所以,这里引进的位图的概念。我们知道,查找一个数据是否存在,它只有两种状态,存在或者不存在,所以可以联想到二进制中的0,1,也是两种状态,每一位不是1就是0,所以,我们可以通过每一个bit为的0,1这两种状态来表示某个数是否存在。
位图概念
所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个 数据存不存在的。

在这里插入图片描述
如上图,(采用int类型)每一个字节8个比特位,那么就可以表示8个数据是否存在,那么一个int类型就能表示32个数据是否存在,数量级已下子就减少了很多。那么,每一个数据对应哪个比特位呢。
首先,先要给位图开辟一定的空间,这里的大小可以根据数据中最大值来进行确定,也可以给一个较大的值,因为位图应用于数量级非常大的数据中,所以实际中可以开辟的大小是自己可以设计的。确定位图得长度后,再看如何将数据对应哪一个bit位。不难看出,因为每个字节占8个bit位,所以只需要确定每个数据在哪一个整数位置就可以,比如数据19,我们除以32得0,则说明19在第0个整数位置中,而对应得bit位,则只除以32取余数部位即可,19模32得19,那么就在该整数位置的第19个bit位中,我们只需要将该bit位置1即可,这样就表示19这个数据存在,将来查找得时候,只需按照该方法判断这一个bit位是否位1,便可知道该数据是否存在

位图的实现

class BitMap
{
public:
	BitMap(size_t len)//外部传入的带查找数组长度
	{
		size = (len/32)+1;
		_bm.resize(size);//给位图开辟好空间
	}
	//将数据存到位图中对应的bit位中
	void insert_to_bitmap(int val)
	{
		int group = val/32;//得到对应某个字节内
		int idx = val%32;
		_bm[group]|=(1<<idx)//将对应bit位置1
	}
	//寻找数据是否存在
	bool find_num(int val)
	{
		int group = val/32;
		int idx = val%32;
		//查找对应bit位是否为1
		if((_bm[group]>>idx)&1) return true;
		else return false;
	}
	//删除数据
	void delete_num(int val)
    {
	    int idx = val / 32;
	    int bitidx = val % 32;
	    //将对应bit位置0
	    _bit[bitidx]&=~(1<<bitidx);
    }
private:
	vector<int> _bm;
	size_t size;
};

测试

void test()
{
  BitMap bit(100);
  bit.Set(4);
  bit.Set(31);
  bit.Set(48);
  bool ret = bit.Test(4);
  cout<<ret<<endl;
  ret = bit.Test(31);
  cout<<ret<<endl;
  ret = bit.Test(48);
  cout<<ret<<endl;
  ret = bit.Test(25);
  cout<<ret<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值