位图以及布隆过滤器

这篇具有很好参考价值的文章主要介绍了位图以及布隆过滤器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要讲解哈希思想的实际应用,位图和布隆过滤器。

位图

讲解位图之前我们先来解答这样一道腾讯的面试题

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】

很多人立马就想到了用哈希表或者红黑树,因为足够快,特别是哈希表,它的查询速度到达了O(1),想法是非常好的,但是我们可以仔细思考一下,这样真的可行吗?
答案是不现实,因为这是四十亿个整数,如果要全部写入到内存中,需要16GB大小的空间,并不是所有的计算机都能装下这些数据,换而言之,就算能完全装下,用这么大的空间去解决这个问题,也是不太好的,面试官也不会满意。

所以这个时候就引入了位图,我们可以想一想,这个问题只是让我们求解一个整数在或者不在,这两种状态,我们只需要用一个bit位就可以标记,例如1代表在,0代表不在。再配合哈希的映射思想,就产生了位图这个数据结构。如果不了解哈希,可以看看我之前的文章,我进行了很详细的讲解,我把链接贴在这里:哈希。

可以先看一下位图的结构和代码是怎么实现的
位图以及布隆过滤器

template<size_t N>
	class bitset {
	private:
		vector<char> bits;
	public:
		bitset()
		{
			bits.resize(N / 8,0);
		}
		//设置对应bit位
		void set(size_t x)
		{

			size_t i = x / 8;
			size_t j = x % 8;

			bits[i] |= (1 << j);
		}
		//重置对应数值bit位
		void reset(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			bits[i] &= ~(1 << j);
		}
		//是否存在
		bool test(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			return bits[i] & (1 << j);
		}
	};

其实再C++库中是有位图结构的:bitset

布隆过滤器

上面的位图结构能很便捷的记录整数在或者不在,那么布隆过滤器是什么呢?

布隆过滤器(Bloom Filter)是一种空间效率非常高的随机数据结构,用于判断一个元素是否可能存在于一个集合中。布隆过滤器可以在时间和空间上做到很高效,但是会有一定的误判率。
布隆过滤器的核心是一个位数组和一组哈希函数。假设位数组的长度是 m,有 k 个哈希函数,则每个元素经过 k 次哈希函数得到 k 个哈希值,将这 k 个值对 m 取模,得到 k 个位置,将这 k 个位置的值都设置为 1。当要查询一个元素时,同样地,将该元素经过 k 次哈希函数得到 k 个哈希值,查询这 k 个位置的值是否都为 1,如果都为 1,则说明该元素可能存在于集合中,如果有任何一个位置的值为 0,则说明该元素一定不存在于集合中。
布隆过滤器的优点在于,它可以很高效地判断一个元素是否存在于一个集合中,而且空间效率非常高,因为它只需要使用一个位数组和一组哈希函数即可。但它的缺点在于,存在一定的误判率,也就是说,有可能某个元素不在集合中,但是经过判断后,布隆过滤器认为它存在于集合中。

简单来说就是一个元素通过K个哈希函数映射K个bit位,布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。
位图以及布隆过滤器

布隆过滤器实现代码:

struct BKDRHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 0;
			for (auto ch : s)
			{
				hash += ch;
				hash *= 31;
			}

			return hash;
		}
	};
	struct APHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 0;
			for (long i = 0; i < s.size(); i++)
			{
				size_t ch = s[i];
				if ((i & 1) == 0)
				{
					hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
				}
				else
				{
					hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
				}
			}
			return hash;
		}
	};
	struct DJBHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 5381;
			for (auto ch : s)
			{
				hash += (hash << 5) + ch;
			}
			return hash;
		}
	};
	template<size_t N,
	class K = string,
	class Hash1 = BKDRHash,
	class Hash2 = APHash,
	class Hash3 = DJBHash>
	class BloomFilter {

	private:
			static const size_t _X = 6;
			bitmap<N* _X> bts;
			size_t len = N * _X;
	public:

		void set(const K& key)
		{
			size_t hash1 = BKDRHash()(key) % len;
			bts.set(hash1);
			
			size_t hash2 = APHash()(key) % len;
			bts.set(hash2);

			size_t hash3 = DJBHash()(key) % len;
			bts.set(hash3);
		}
		bool test(const K& key)
		{
			if (!bts.test(BKDRHash()(key) % len))
			{
				return false;
			}
			if (!bts.test(APHash()(key) % len))
			{
				return false;
			}
			if (!bts.test(DJBHash()(key) % len))
			{
				return false;
			}
			return true;
		}
	};

布隆过滤器使用的哈希函数越多误判率越低,但是占用的空间也就越大。用三个哈希函数是比较合适的。

这就是位图和布隆过滤器的原理和实现,如果对您有所帮助,点个赞和关注吧!文章来源地址https://www.toymoban.com/news/detail-482897.html

到了这里,关于位图以及布隆过滤器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 哈希的应用--位图和布隆过滤器

    位图(Bitset)是一种数据结构,用于表示一组布尔值,其中每个元素通常对应于一个位或一个二进制值,可以存储0或1。位图在计算机科学和计算机工程中经常用于各种应用,特别是在位级别的标志、掩码和快速查找中。以下是位图的一些关键特点: 二进制表示 :位图中的每

    2024年02月08日
    浏览(40)
  • C++哈希应用——位图布隆过滤器

    用哈希表存储用户记录,缺点是需要消耗较大的内存;用位图存储用户记录,缺点是位图一般处理整形,内容是字符串或者自定义类型就很勉强。基于以上,若将哈希和位图结合,称为布隆过滤器,会不会把上面的问题都解决了呢? 概念 布隆过滤器是一种概率型数据结构。

    2024年02月04日
    浏览(40)
  • [C++]哈希应用之位图&布隆过滤器

               主厨:邪王真眼 主厨的主页:Chef‘s blog   所属专栏:c++大冒险        我们之前学习了哈希表,哈希表通过映射关系,实现了O(1)的复杂度来查找数据,哈希在实践中是一个非常重要的思想,今天要学习的就是哈希思想的两大应用:位图与布隆过滤器 给 40 亿个

    2024年04月15日
    浏览(29)
  • 【C++】位图/布隆过滤器+海量数据处理

    ✍ 作者 : 阿润菜菜 📖 专栏 : C++ 题目 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 大多数人上来会想到这两种方法:1. 遍历,时间复杂度O(N)2. 排序(O(NlogN)),利用二分查找: logN 但是第一种效率太低了,需要一个

    2024年02月06日
    浏览(37)
  • 【C++】哈希应用:位图 哈希切分 布隆过滤器

    我走后,他们会给你们加班费,会给你们调休,这并不是他们变好了,而是因为我来过。------龙哥 1. 大厂经典的面试题,给你40亿个不重复的无符号整数,让你快速判断一个数是否在这40亿个数中,最直接的思路就是遍历这40亿个整数,逐一进行比对,当然这种方式可以倒是可

    2023年04月09日
    浏览(33)
  • C++【位图/布隆过滤器—海量数据处理】

    先看下面的一道题 : 1.有40亿个不重复的无符号整数,无序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 如果我们放到哈希表或红黑树中或用排序和二分查找这两种方法。 前两种方法不可行,因为40亿个整数占用大约16G的内存空间,第一要排序需要先把数

    2024年02月09日
    浏览(49)
  • C++ 哈希思想应用:位图,布隆过滤器,哈希切分

    1.问题 给你40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中? 2.分析 1 Byte = 8 bit 1KB = 1024 Byte 1MB = 1024KB = 1024 1024 大约= 10的6次方Byte 1GB = 1024MB = 1024 10的6次方 大约= 10的9次方Byte = 10亿字节 因此4GB 约等于40亿字节 其实最快的方式就是

    2024年04月17日
    浏览(34)
  • 【C++学习】哈希的应用—位图与布隆过滤器

    文章简介 : 在这篇文章中,你会学习到关于哈希思想的最常见的两个应用,也就是 位图 与 布隆过滤器 , 文章会讲解位图和布隆过滤器的概念,底层实现,对应的适应的场景,以及相关经典 海量数据面试题 及解析。 所谓位图,就是用每一位来存放某种状态,适用于 海量

    2024年04月14日
    浏览(50)
  • 【C++高阶(六)】哈希的应用--位图&布隆过滤器

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 哈希最常用的应用是unordered 系列的容器,但是当面对海量数据 如100亿个数据中找有没有100这 个数时,使用无序容器的话内存放不下 所以哈希

    2024年02月05日
    浏览(35)
  • 哈希与位图的结合--布隆过滤器与哈希切分

    上一章讲了位图,我们知道了在海量数据中查找一个数是否存在,可以用每一个比特位标识。 但是位图只能处理整数,要是字符串或者其它的呢,位图便无法处理了,这个时候便需要用到布隆过滤器了. 目录 布隆过滤器提出 布隆过滤器概念 布隆过滤器的实现以及最优值  哈

    2024年02月12日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包