c++位图-布隆

说起位图和布隆,也是一把辛酸泪了。毕竟智商受限啊,今天研究了一下午,终于明白了些许,赶紧整理起来。
什么是位图:
1) 其实它也是一种哈希表,只不过它是以位(bit)为单位的,我们平常都是以字节(也是内存中可操作的最小单位)·相当于一个二维数组,一维相当于是字节,二维就要定义到位了
假设是用int来说,一个int是4个字节,一个字节是8位,因此一个整型就是32位。那么我们要定义到一个具体的位应该怎么办,假设这个数是num。那么就是num/32–>得到位于哪个字节 num%32–>得到位于哪个比特位上。
2)位图,就是用每一位来存放某种状态,这里要注意存放的是状态(有/米有)而不是把这个数据直接存放进去了,类似于这样
在这里插入图片描述
位图的作用
适用于数据量庞大的场合,通常是用来判断某个数据存不存在,位图可以对整型进行快速的排序和去重。
再来看它的代码实现(很重要)

class BitSet
{
	public:
		BitSet(size_t range)

		{
			_bs.resize((range >>5) + 1,0);//开空间,比如说范围为64,64/32=2,需要两个int,如果范围小于32,至少需要一个字节因此还需要加1,开始的时候每一位都是0,也可以不写,因为vector缺省值就是0
		}
		//存储
		void Set(int num)//把某一位置1
		{
			int index=num >> 5;
			int bitIndex = num % 32;
			_bs[index] |= (1 << bitIndex);
		}

		int Find(int number)
		{
			int index = number >> 5;
			int bitIndex = number % 32;
			return (_bs[index] >> bitIndex) & 1;

		}


		void Reset(int number)
		{ 
			int index = number >> 5;
			int bitIndex = number % 32;
			_bs[index] &= (~(1 << bitIndex));
		}
private:
	vector<int> _bs;
};

好了,下面来看布隆过滤器
布隆?不要意外,这就是一个人名,所以不要纠结为啥要叫布隆好叭~~~嘻嘻嘻
那我们在使用位图的时候,有没有发现一个问题,数据都是整型的哈,那要是其他类型咋办?比如是字符串类型(链接),别担心,布隆就为我们提供了解决方法
什么是布隆过滤器
是一种概率性的容器,就是说结果不一定准确,不过也别担心,一般情况下,准确率还是很高的。
他就是利用哈希函数,把字符串通过一个映射关系转换成整型,我们想想,如果只用一个哈希函数来映射 的话会出现什么情况,是不是可能好多个字符串都会映射成相同的整型值,这就造成了误判的情况,显然不是我们想要的,那怎么办?很简单,多用几个哈希函数,当然是越多越好,但是太多的话显然会造成代码量大等问题,所以这里就用3个。
我们想,如果一个位图中的状态是0----》说明要找的这个数一定不存在,如果是1—》
这个数不一定存在
下面我们来看代码实现:

struct HFun1
{
	size_t operator()(const string& str)
	{
		size_t hash = 0;
		for (auto& ch : str)
		{
			hash = hash * 131 + ch;
		}
		return hash;
	}
};
struct HFun2
{
	size_t operator()(const string& str)
	{
		size_t hash = 0;
		for (auto& ch : str)
		{
			hash = hash * 65599 + ch;
		}
		return hash;
	}
};
/*
size_t magic = 63689;
while (size_t ch = (size_t)*str++)
{
hash = hash * magic + ch;
magic *= 378551;
*/
struct HFun3
{
	size_t operator()(const string& str)
	{
		size_t hash = 0;
		size_t magic = 63689;
		for (auto& ch : str)
		{
			hash = hash * magic + ch;
			magic *= 378551;
		}
		return hash;
	}
};
//布隆过滤器---多位的位图(非整数信息的保存---》整数---》映射位置)
template <
class T,
class HFun1,
class HFun2,
class HFun3>
class BloomFilter
{
public:
	//k==(m/n)*ln2
	//m:bitSet大小
	//n:元素个数,num(链接个数)
	//k:哈希函数的数量
	//m=k*/ln2=1.4*k*n=1.4*3*n=4.2n,所以开5
	BloomFilter(size_t number)//要保存这么多个数据,实际就是范围,比如说存了10个链接

		:_bs(5*number)
		, _bitcount(5*number)
	{}
	void Set(const T& data)//可以存任意类型的数据,如果不是整数,,通过哈希函数转成整数
	{
		int index1 = HFun1()(data) % _bitcount;//给一个匿名对象
		int index2 = HFun2()(data) % _bitcount;
		int index2 = HFun2()(data) % _bitcount;
		_bs.Set(index1);
		_bs.Set(index2);
		_bs.Set(index3);
	}
	bool Find(const T& data)
	{
		int index1 = HFun1()(data) % _bitcount;//给一个匿名对象
		if (!_bs.Find(index1))//有一个地方为0就是不存在的
			return false;
		int index2 = HFun2()(data) % _bitcount;
		if (!_bs.Find(index2))
			return false;
		int index2 = HFun2()(data) % _bitcount;
		if (!_bs.Find(index3))
			return false;
		return true;//存在误判,估计的
	}
	//不提供删除操作
private:
	BitSet _bs;
	size_t _bitcount;//位数
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
位图(Bitmap)和布隆过滤器(Bloom Filter)都是常用的数据结构,用于处理大规模数据集合,但它们有着不同的应用场景和用途。 位图是一种压缩数据结构,用于快速地判断某个元素是否在集合中。位图实现方式是将每个元素映射到一个二进制位上,如果该元素存在于集合中,则将对应的二进制位标记为1,否则标记为0。这样,当需要查询某个元素是否在集合中时,只需要查找对应的二进制位即可。由于位图实现方式非常简单,因此可以快速地进行插入和查询操作,而且占用的空间也非常小,适合处理大规模数据集合。 布隆过滤器也是一种快速判断元素是否存在于集合中的数据结构,但其实现方式与位图略有不同。布隆过滤器使用一组哈希函数将元素映射到多个二进制位上,并将对应的二进制位标记为1。当查询某个元素是否在集合中时,将该元素进行哈希映射,并查找对应的二进制位,如果所有的二进制位都被标记为1,则说明该元素可能存在于集合中,否则可以确定该元素不存在于集合中。布隆过滤器的优点是可以快速地判断一个元素不存在于集合中,而且占用的空间也比较小,但存在误判率的问题。 因此,位图布隆过滤器虽然都可以用来处理大规模数据集合,但它们的实现方式和应用场景有所不同。位图适用于需要快速地判断某个元素是否在集合中的场景,而布隆过滤器适用于需要快速地判断一个元素不存在于集合中的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值