位图以及布隆过滤器

news2024/11/16 19:39:02

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

位图

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

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

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

这就是位图和布隆过滤器的原理和实现,如果对您有所帮助,点个赞和关注吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Seata TCC 模式理论学习、生产级使用示例搭建及注意事项 | Spring Cloud55

一、前言 通过以下系列章节&#xff1a; docker-compose 实现Seata Server高可用部署 | Spring Cloud 51 Seata AT 模式理论学习、事务隔离及部分源码解析 | Spring Cloud 52 Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53 Seata XA 模式理论学习、使用…

STL——set容器、map容器

初识STL **set容器/multiset容器****set容器——构造和赋值****set容器——大小和交换****set容器——插入和删除****set容器的查找和统计****set和multiset的区别****set的相关操作源码&#xff1a;****multiset的相关操作源码** **pair使用——pair队组的创建****set容器——…

FreeRTOS-定时器详解

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转FreeRTOS &#x1f4ac;保持…

2023全国计算机二级考试时间(全年各阶段考试时间安排)

2023全国计算机二级考试时间(全年各阶段考试时间安排) 2023年全国计算机二级考试时间分别为&#xff1a;3月25日至27日(上半年3月)、9月23日至25日(下半年9月)。 其中3月和9月开考全部级别全部科目&#xff0c;5月和12月考试开考一、二级全部科目&#xff0c;各省级承办机构可根…

RabbitMQ集群部署之镜像模式

RabbitMQ集群的普通模式中&#xff0c;一旦创建队列的主机宕机&#xff0c;队列就会不可用。不具备高可用能力。如果要解决这个问题&#xff0c;必须使用官方提供的镜像集群方案。 官方文档地址&#xff1a;https://www.rabbitmq.com/ha.html 1.镜像模式的特征 默认情况下&a…

离心式冷水机组

离心式冷水机组是利用电作为动力源&#xff0c;氟利昂制冷剂在蒸发器内蒸发吸收载冷剂水的热量进行制冷&#xff0c;蒸发吸热后的氟利昂湿蒸汽被压缩机压缩成高温高压气体&#xff0c;经水冷冷凝器冷凝后变成液体&#xff0c;经膨胀阀节流进入蒸发器再循环。从而制取7℃-12℃冷…

解决jvm内存溢出的方法

上一篇问题讲了怎么实现jvm内存溢出,现在已经实现了,那怎么去解决它呢. java.lang.OutOfMemoryError: GC overhead limit exceeded 简单来说&#xff0c;java.lang.OutOfMemoryError: GC overhead limit exceeded发生的原因是&#xff0c;当前已经没有可用内存&#xff0c;经…

【IMX6ULL驱动开发学习】06.APP与驱动程序传输数据_自动创建设备节点(hello驱动)

一、APP与驱动之间传输数据 /*驱动从APP获取数据*/ unsigned long copy_from_user(void *to, const void *from, unsigned long n)/*驱动传输数据到APP*/ unsigned long copy_to_user(void *to, const void *from, unsigned long n)二、使用copy_to_user、copy_from_user在AP…

如何把视频声音转成文字?分享三个实用的方法!

在日常学习中&#xff0c;有些小伙伴可能想将视频课程中老师的讲解内容整理出来&#xff0c;但是逐字逐句地打字既低效又耗时。那么&#xff0c;如何将视频声音快速转换为文字呢&#xff1f;答案是使用记灵在线工具&#xff01;下面我将分享几种使用记灵在线工具快速将视频声音…

Raft is not great?

Raft相比于paxos不好的地方有下面这些地方 1.Term raft的逻辑时钟是通过term&#xff0c;和votefor来确定的&#xff0c;同时&#xff0c;raft的votefor只能是None < 有&#xff0c;有的话&#xff0c;就不可比&#xff0c;也就是一个偏序关系。这个不可比的特性会增加选举…

Javaweb学习路线(2)——Maven

一、概念 Maven 是 apache 旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 二、作用 依赖管理&#xff1a; 动态管理jar包&#xff0c;避免版本冲突。统一项目结构&#xff1a; 提供标准、统一的项目结构。项目构建&#xff1a; 标准跨平台的自动化项目…

深入探讨软件测试的质量度量指标

本文的目的是介绍项目中使用到主要质量指标&#xff0c;这些质量指标可以分为以下三类&#xff1a; 质量保证过程指标生产事故管理指标度量质量文化指标 质量保证过程指标 质量保证指标可以通过测试覆盖率来度量功能和非功能测试的覆盖率&#xff0c;同时也可以根据测试发现…

shell学习记录(函数)

Shell 函数 linux shell 可以用户定义函数&#xff0c;然后在shell脚本中可以随便调用。 shell中函数的定义格式如下&#xff1a; [ function ] funname [()] { action; [return int;] } 说明&#xff1a; 1、可以带function fun() 定义&#xff0c;也可以直接fun()…

对“java子类不能继承父类构造方法“的理解

目录 子类构造函数&#xff0c;什么时候需要写&#xff0c;什么时候可以不写&#xff1f;为什么要这么设计&#xff1f;子类已经继承父类&#xff0c;为什么就不能继承父类的构造器了&#xff1f;子类直接用父类的构造器不就行了&#xff1f; 子类构造函数&#xff0c;什么时候…

今年适合进入软件测试行业吗?

对于“自己适不适合转行做软件测试&#xff1f;”一直都是测试行业里的热门话题。随着近几 年IT互联网行业的快速发展&#xff0c;软件测试岗位也受到越来越多人的关注&#xff0c;因此有很多人都想要从事这一行业&#xff0c;这里主要分为两类人&#xff0c;一种是刚毕业的应届…

【Deno】极简入门

极简系列 极简入门 简介 Deno是一个 JavaScript/TypeScript 的运行时&#xff0c;默认使用安全环境执行代码&#xff0c;有着卓越的开发体验。 Deno建立在 V8、Rust 和 Tokio 的基础上。 优势 适合不喜欢复杂配置开箱即用的人群&#xff08;如本人小溪&#xff09; 安全性…

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上层的…

Spring-Bean基础

文章目录 什么是 BeanDefinition如何获取BeanDefinition如何将BeanDefinition注册到容器中Bean的初始化操作Bean的销毁操作 什么是 BeanDefinition BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口&#xff0c;包含如下信息&#xff1a; 如何获取BeanDefin…

STL学习笔记

STL学习笔记 Vector void VectorTest() {vector<int> vect;vect.push_back(1);vect.push_back(20);vect.push_back(12);vect.push_back(12);vect.push_back(12);sort(vect.begin(),vect.end());for(vector<int>::iterator itervect.begin();iter!vect.end();iter…

osg利用setNodeMask和Switch隐藏节点用法说明

目录 1. 用法及差异点说明 2.利用NodeMask隐藏节点 2. Switch节点 3. NodeMask和Switch混用 1. 用法及差异点说明 在osg中使Node隐藏方式有两种&#xff0c;一种是设置NodeMask&#xff0c;另外一种是使用osg的Switch类来控制。两者的区别&#xff1a;前者只是看不到&#…