【1++的数据结构】之哈希(二)

news2024/12/24 2:25:20

👍作者主页:进击的1++
🤩 专栏链接:【1++的数据结构】


文章目录

  • 一,前言
  • 二,位图
    • 1. 位图
    • 2. 位图的应用
  • 三,布隆过滤器

一,前言

上一节我们讲解了哈希表,简单的了解了哈希思想,这一节我们对哈希思想进行更深入的了解,对其应用进行学习。大家坐稳了,学习的快车又要发动了!!!
在这里插入图片描述

二,位图

1. 位图

什么叫位图呢?
位图就是用每一位来存储一种状态。位是表示信息的最小单位,每一位存储一种状态,那么我们可以将每一位的状态与数据映射。那么便可以用较少的内存去处理海量的数据。通常用其判断某个数据存不存在。
接下来我们进行位图的实现:
来看代码:

template<size_t N>
	class Bit_set
	{
	public:
		Bit_set()
		{
			_bit_table.resize(N / 8 + 1, 0);
		}
		void set(const size_t& key)
		{
			//锁定位置
			size_t i = key / 8;
			size_t j = key % 8;
			//将那一位置为1
			_bit_table[i] |= (1 << j);

		} 

		void reset(const size_t& key)
		{
			//锁定位置
			size_t i = key / 8;
			size_t j = key % 8;
			//将那一位置为0
			_bit_table[i] &= ~(1 << j);
		}

		bool test(const size_t& key)
		{
			//锁定位置
			size_t i = key / 8;
			size_t j = key % 8;
			//检查那一位是否为1
			return _bit_table[i] & (1 << j);
		}
	private:
		vector<char> _bit_table;

	};

总的思路就是开一个有N个位大小的空间(N应该比元素集合中的最大值还要大),然后将数据(整型)映射到位图中的位置:即第几个char中的第几位,然后将其进行置1,置0,或是检查那位是否为1。

2. 位图的应用

  1. 快速查找某个数据是否在一个集合中
    此题可直接使用位图,进行查找。
  2. 排序 + 去重
    由于位图只可以表示其状态(在或不在)因此其天生就有去重的特性,其排序,只需将我位图遍历一遍,便可以得到升序的元素集合。
void test2()
	{
		size_t N = 100;
		Bit_set<100> s1;
		int arr[] = { 1,5,3,7,0,10,9,8,3 };
		for (auto& e : arr)
		{
			s1.set(e);
		}

		for (size_t i = 0; i < N; i++)
		{
			if (s1.test(i))
			{
				cout << i << endl;
			}

		}
	}

在这里插入图片描述

  1. 求两个集合的交集、并集等
    我们只需要创建两个相同大小的对象,然后各自进行set,最后一起遍历。。。。。
void test3()
	{
		size_t N = 100;
		Bit_set<100> s1;
		Bit_set<100> s2;
		int arr1[] = { 1,5,3,7,0,10,9,8,3 };
		int arr2[] = { 1,10,3,7,11,10,2,8,4 };

		for (auto& e : arr1)
		{
			s1.set(e);
		}

		for (auto& e : arr2)
		{
			s2.set(e);
		}

		for (size_t i = 0; i < N; i++)
		{
			if (s1.test(i) && s2.test(i))
			{
				cout << i << endl;
			}

		}
	}

在这里插入图片描述

  1. 找出现两次的元素
    既然一个位只能表示一种状态,那么两个位是不是就能表示四种状态(一次没出现,出现一次,出现两次,出现两次以上)
template<size_t N>
	class two_bit
	{
	public:
		void set(const size_t& key)
		{
			if (_bits1.test(key) == false && _bits2.test(key) == false)
			{
				_bits2.set(key);
				_bits1.reset(key);
			}
			else if (_bits1.test(key) == false && _bits2.test(key) == true)
			{
				_bits1.set(key);
				_bits2.reset(key);
			}
			else 
			{
				_bits1.set(key);
				_bits2.set(key);
			}
			
		}

		bool test(const size_t& key)
		{
				
			return (_bits1.test(key) == true && _bits2.test(key) == false);
		}
	private:
		Bit_set<N> _bits1;
		Bit_set<N> _bits2;

	};


void test3()
	{
		two_bit<100> t1;
		int arr[] = { 1,4,6,2,3,7,9,10,2,6,2 };
		for (auto& e : arr)
		{
			t1.set(e);
		}
		cout<<t1.test(2)<<endl;
		cout << t1.test(6) << endl;
		cout << t1.test(1) << endl;
	}

三,布隆过滤器

什么是布隆过滤器?
布隆过滤器是用多个哈希函数,将一个数据元素映射到位图结构中。此方式不仅可以提升效率,也可以节省空间。
以下是布隆过滤器的实现:

template<class K,size_t N>
	class BloomFilter
	{
	public:
		void set(const K& key)
		{
			size_t len = N * 5;
			size_t hash1 = DJBHash()(key) % len;
			size_t hash2 = BKDRHash()(key) % len;
			size_t hash3 = APHash()(key) % len;

			_bitset.set(hash1);
			_bitset.set(hash2);
			_bitset.set(hash3);
		}

		void reset(const K& key)//普通的删除可能会影响其他值

		bool test(const K& key)
		{
			size_t len = N * 5;
			size_t hash1 = DJBHash()(key) % len;
			size_t hash2 = BKDRHash()(key) % len;
			size_t hash3 = APHash()(key) % len;
			if (!_bitset.test(hash1))
				return false;
			if (!_bitset.test(hash2))
				return false;
			if (!_bitset.test(hash3))
				return false;

			return true;

		}
	private:
		Bit_set<N* 5> _bitset;
	};

布隆过滤器的优点及其缺陷:

  1. 增加和查询元素的时间复杂度位O(K) K为哈希函数的个数。
  2. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
  3. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
  4. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能

缺点:

  1. 有误判,能够判定某一元素一定不在,但不能够判定该元素一定在。
  2. 一般情况下不能够进行删除
  3. 不能够获取元素本身

在这里插入图片描述

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

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

相关文章

探索工业4.0:数字孪生如何重塑工业生产流程?

在过去的几十年里&#xff0c;工业生产经历了从机械化、自动化到数字化的巨大转变。随着工业4.0的到来&#xff0c;我们正处于第四次工业革命的边缘&#xff0c;这次革命将由数字孪生技术引领。本文将深入探讨数字孪生在工业生产中的应用和潜力。 数字孪生&#xff08;Digital …

第六章 进程管理与系统监控

第六章 进程管理与系统监控 ​ 一个具有较好的安全性和稳定性的系统是用户所需要的。无论进行何种操作和业务处理&#xff0c;用户都希望系统始终处于安全、稳定的状态。因此&#xff0c;即时地进行系统的进程管理和系统监控工作是保证系统安全、稳定的状态。 1.进程管理 1.…

C++项目实战——基于多设计模式下的同步异步日志系统-⑥-日志等级类与日志消息类设计

文章目录 专栏导读日志等级类设计日志等级划分to_string函数设计日志等级类整理 日志消息类设计 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&#xff0c;阿里云专家博主&#xff0c;…

第4篇 vue的 ECMAScript 6的学习

一 ECMAScript 6 1.1 ECMAScript 6 ECMAScript 和 JavaScript 的关系是&#xff0c;前者是后者的规格&#xff0c;后者是前者的一种实现&#xff08;另外的 ECMAScript 方言还有 Jscript 和 ActionScript&#xff09;。 因此&#xff0c;ES6 既是一个历史名词&#xff0c;也…

java+ssm+mysql高校图书管理系统

项目介绍&#xff1a; 本系统为基于jspssmmysql的高校图书管理系统&#xff0c;包含管理员、学生角色&#xff0c;功能如下&#xff1a; 管理员&#xff08;高级管理和普通管理&#xff09;&#xff1a;用户管理&#xff08;管理员和学生管理&#xff09;&#xff1b;图书管理…

ps制作gif动图

最后存储就可以了

问道管理:历史市净率在哪看?

市净率是评价一家企业股票价格是否合理的一项重要指标&#xff0c;并且也能够反映企业的财务状况。前史市净率则是指某家企业在曩昔一段时间内&#xff08;比方一年或三年&#xff09;的市净率平均值。那么&#xff0c;前史市净率在哪里能够查询呢&#xff1f;本文将从多个视点…

华为OD机试 - 一种字符串压缩表示的解压(Java 2022 Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路1、题意2、根据题意&#xff0c;不合法方式如下&#xff1a;3、解题思路 五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为O…

【CSS系列】writing-mode —— 文字方向(水平/垂直;左右/右左)

文章目录 一、引子二、writing-mode1.语法horizontal-tb&#xff08;默认&#xff1a;水平方向&#xff0c;文字 从左到右&#xff0c;行 从上到下&#xff09;vertical-rl&#xff08;垂直方向&#xff0c;文字 从上到下&#xff0c;行 从右到左&#xff09;vertical-lr&#…

Go基础16-defer的运作机制及常见用法

defer的运作离不开函数&#xff0c;这至少有两层含义&#xff1a; ● 在Go中&#xff0c;只有在函数和方法内部才能使用defer&#xff1b; ● defer关键字后面只能接函数或方法&#xff0c;这些函数被称为deferred函数。defer将它们注册到其所在goroutine用于存放deferred函数…

IAM、EIAM、CIAM、RAM、IDaaS 都是什么?

后端程序员在做 ToB 产品或者后台系统时&#xff0c;都不可避免的会遇到账号系统、登录系统、权限系统、日志系统等这些核心功能。这些功能一般都是以 SSO 系统、RBAC 权限管理系统等方式命名&#xff0c;但这些系统合起来有一个专有名词&#xff1a;IAM。 IAM IAM 是 Identi…

视频直播点播平台EasyDSS流媒体服务器按时间调用录像,提示数据查询错误是什么原因?

EasyDSS能实现视频流媒体的上传、转码、存储、录像、推拉流、直播、点播等功能&#xff0c;具备超低延迟、超高画质、超大并发访问量等特点&#xff0c;可应用在多样化的场景中&#xff0c;如&#xff1a;在线课堂、教育直播、校园活动直播、企业培训、游戏直播等。为了便于用户…

【面试经典150 | 双指针】两数之和

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;暴力枚举方法二&#xff1a;哈希表方法三&#xff1a;二分法方法四&#xff1a;双指针 知识回顾写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢…

[NLP]LLM--使用LLama2进行离线推理

一 模型下载 二 模型推理 本文基于Chinese-LLaMA-Alpaca-2项目代码介绍&#xff0c;使用原生的llama2-hf 克隆好了Chinese-LLaMA-Alpaca-2 项目之后&#xff0c;基于GPU的部署非常简单。下载完成以后的模型参数(Hugging Face 格式)如下&#xff1a; 简单说明一下各个文件的作…

【精品】git commit 代码规范

规范 格式&#xff1a; type(scope) : subject type&#xff08;必须&#xff09; : commit 的类别&#xff0c;只允许使用下面几个标识&#xff1a; feat : 新功能fix : 修复bugdocs : 文档改变style : 代码格式改变refactor : 某个已有功能重构perf : 性能优化test : 增加测…

6.2.2 【MySQL】InnoDB中的索引方案

上边之所以称为一个简易的索引方案&#xff0c;是因为我们为了在根据主键值进行查找时使用二分法快速定位具体的目录项而假设所有目录项都可以在物理存储器上连续存储&#xff0c;但是这样做有几个问题&#xff1a; InnoDB 是使用页来作为管理存储空间的基本单位&#xff0c;也…

未来3-5年,前端低代码化,具体往哪个方向发展更好就业?

最近发现一个有趣的现象&#xff0c;好像是要紧追AIGC的速度一样&#xff0c;我的朋友圈也是越来越多人每天抒发关于“前端开发新方向”的见解。 且其中不仅是关于AI的讨论&#xff0c;还把不少资深人士把低代码也拉出来溜了一圈&#xff0c;不仅是开发人员&#xff0c;产品经理…

构建企业分支网络

构建企业分支网络 目录 1.1 项目背景 1.2 项目拓扑 1.3 项目需求 1.4 设备选型 1.5 技术选型 1.6 地址规划 1.6.1 交换设备地址规划表 1.6.2 路由设备地址规划表 1.6.3 ISP设备地址规划表 1.6.4 终端地址规划表 1.6.4.1 VLAN 规划 1.7 VLAN 规划 1.8 项目实施 1.…

git撤回 不小心 commit 进去的文件

我时候 我们可能讲一下不想提交的文件 不小心commit了进去 我们可以通过 git reset HEAD~来撤回刚才的添加记录

iNeuOS工业互联网操作系统V5,视图建模(WEB组态)升级

针对工业来讲&#xff0c;特殊是流程行业&#xff0c;视图建模&#xff08;Web组态&#xff09;是必不可少应用场景&#xff0c;因为有很多工序要直观的展示工艺流程图。 对于一个工厂&#xff0c;少则几十张工艺流程图&#xff0c;多则上百张工艺流程图&#xff0c;还得支持灵…