C++语法(24) 哈希应用

C++语法(23)-- 模拟实现unordered_set和unordered_map_哈里沃克的博客-CSDN博客icon-default.png?t=N4P3https://blog.csdn.net/m0_63488627/article/details/130449452?spm=1001.2014.3001.5501 

目录

1.位图

1.定义

2.实现

3.应用

4.特点

2.布隆过滤器

1.介绍

2.设计场景

3.实现

4.应用


1.位图

1.定义

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

2.实现

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

构造函数的实现:由于有N个数,而char可以存储8位的信息,那么最后有N/8个,不过由于除法会切割后面的多余,所以我们需要对N/8+1处理。


求出在哪一个char中:size_t i = x / 8;
求出在char的哪一位上:size_t j = x % 8;

插入的逻辑(或上1左移j位):_bits[i] |= (1 << j);

删除的逻辑(和上1左移j位后取非):_bits[i] &= (~(1 << j));

判断是否在的逻辑:return _bits[i] & (1 << j); 没有则返回0,找到返回非零

namespace MY
{
	template<size_t N>
	class bit_set
	{
	public:
		bit_set(size_t N)
		{
			_bits.resize(N / 8 + 1, 0);
		}

		void set(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			_bits[i] |= (1 << j);
		}

		void reset(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			_bits[i] &= (~(1 << j));
		}

		bool text(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			return _bits[i] & (1 << j);
		}
	private:
		vector<char> _bits;
	};
}

3.应用

其实位图的使用很灵活,我们不是非要一个数对应一个比特位这么狭隘;我们可以根据需求,定义一个数对应比特位的多少,;或许用多个位图一起使用,这样就能实现更广的范围。

1. 给定100亿个整数,设计算法找到只出现一次的整数?

我们可以定义两个位:00为0次,01为1次,10为1以上。这样就能实现。

当然使用两个位图也可以实现。


2. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

两个先去重,随后用两个位图,如果都有数据说明是交集。


3. 位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
我们可以定义两个位:00为0次,01为1次,10为2次,11为3次以及以上。只需要找01和10即可满足要求。

4.特点

优点:1.节省空间 2.快

缺点:1.一半需要数据比较集中,如果过于分散,空间的消耗会增大 2.只针对整型

2.布隆过滤器

1.介绍

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间
布隆过滤器的改进:映射多个位置,降低误判率

2.设计场景

1.注册昵称不允许出现重复的,布隆过滤器用于昵称的查重

2.黑名单列表

3.实现

1.不能实现删除,以为过滤器特殊的误判机制

2.set就是将hashFunc得到的结果映射到位图中,将所有的Func得到位图的结果都进行判1处理

3.test,将所有hash值对应的位图的数据找到,如果没有在位图中说明该数据一定没有出现,如果找到,说明有可能出现误判,那么具体后续的处理还需要设计

4.高效率的设置为:HashFuncN=(N/X)*ln2

HashFuncN:Func函数有几个

N:数据的多少

X:位图的大小

namespace MY
{
	struct BKDRHash
	{
		size_t operator()(const string& key)
		{
			size_t hash = 0;
			for (auto ch : key)
			{
				hash *= 131;
				hash += ch;
			}
			return hash;
		}
	};

	struct APHash
	{
		size_t operator()(const string& key)
		{
			unsigned int hash = 0;
			int i = 0;

			for (auto ch : key)
			{
				if ((i & 1) == 0)
				{
					hash ^= ((hash << 7) ^ (ch) ^ (hash >> 3));
				}
				else
				{
					hash ^= (~((hash << 11) ^ (ch) ^ (hash >> 5)));
				}

				++i;
			}

			return hash;
		}
	};

	struct DJBHash
	{
		size_t operator()(const string& key)
		{
			unsigned int hash = 5381;

			for (auto ch : key)
			{
				hash += (hash << 5) + ch;
			}

			return hash;
		}
	};

	struct JSHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 1315423911;
			for (auto ch : s)
			{
				hash ^= ((hash << 5) + ch + (hash >> 2));
			}
			return hash;
		}
	};

	//HashFuncN=(N/X)*ln2
	template<size_t N , 
		size_t X = 6,
		class K = string, 
		class HashFunc1 = BKDRHash, 
		class HashFunc2 = APHash, 
		class HashFunc3 = DJBHash,
		class HashFunc4 = JSHash>
	class BloomFilter
	{
	public:
		bool set(const K& key)
		{
			size_t hash1 = HashFunc1()(key) % (X * N);
			size_t hash2 = HashFunc2()(key) % (X * N);
			size_t hash3 = HashFunc3()(key) % (X * N);
			_bs.set(hash1);
			_bs.set(hash2);
			_bs.set(hash3);
			return true;
		}

		bool test(const K& key)
		{
			size_t hash1 = HashFunc1()(key) % (X * N);
			if (!_bs.test(hash1))
			{
				return false;
			}
			size_t hash2 = HashFunc2()(key) % (X * N);
			if (!_bs.test(hash2))
			{
				return false;
			}
			size_t hash3 = HashFunc3()(key) % (X * N);
			if (!_bs.test(hash3))
			{
				return false;
			}

			return true;//可能会出现重复的误判
		}

	private:
		std::bitset<N * X> _bs;
	};
}

误判率高,空间开的多就能解决。不过过分追求误判率的低会导致开辟的空间消耗过大。

4.应用

1. 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出
精确算法和近似算法

近似算法:对其中一个文件放入布隆过滤器,另一个进行比较。找出来的交集比真正的交集多,以为会出现误判。

精确算法:假设每个文件的query为50byte,100亿个query有500G。将两个大文件分别切分,按照哈希思路映射(/1000)到单位为0.5G的小文件Ai,Bi。A0文件对应B0文件...A999文件对应B999文件,取出一对文件,两个文件去重后再进行取交集,依次找就能得到精确的交集。


2. 如何扩展BloomFilter使得它支持删除元素的操作

其实很简单,之所以不行是因为我们设计的位图只表示存在不存在,因此只有01表示,删除就会出现误判。那么我们只需要设计可以计数的布隆过滤器就能解决可以删除的问题。不过设计出支持删除的布隆过滤器就意味着开辟一个巨大的空间,有时候空间消耗太大反而不值当的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE01_初识Java

JavaSE-01【初识Java】 第一章&#xff1a;Java开发序言 1.1 Java语言概述 1、什么是Java语言 Java语言是美国Sun公司&#xff0c;在1995年推出的高级编程语言。 所谓编程语言&#xff0c;就是计算机语言&#xff0c;人们可以使用编程语言对计算机下达指令&#xff0c;让计…

LVGL学习(2):图片的转换和显示

我们在设计UI的过程中可能需要显示一些图片&#xff0c;本篇文章将介绍如何转换并显示一个固定的图片到lv_img中。 文章目录 1 图片转换1.1 GUI Guider1.2 在线转换 2 图片的显示 1 图片转换 和之前我写的一篇字体转换的文章一样&#xff1a;LVGL学习(1)&#xff1a;中文字体…

UnityVR--组件5--Animation动画

目录 新建动画Animation Animation组件解释 应用举例1&#xff1a;制作动画片段 应用举例2&#xff1a;添加动画事件 Animator动画控制器 应用举例3&#xff1a;在Animator中设置动画片段间的跳转 本篇使用的API&#xff1a;Animation、Animator以及Animator类中的SetFlo…

MySQL学习(联结,组合查询,全文本搜索)

联结 SQL最强大的功能之一就是能在数据检索查询的执行中联结表&#xff1b; 关系表 为什么要使用关系表&#xff1f; 使用关系表可以储存数据不重复&#xff0c;从而不浪费时间和空间&#xff1b;如果有数据信息变动&#xff0c;只需更新一个表中的单个记录&#xff0c;相关…

Zabbix(一)

介绍 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 功能组件 Server &#xff1a; Zabbix server是zabbix软件的核心组件 Zabbix agent向其报告可用性、系统完整性和统计信息 Zabbix server存储所有的配置信息、统计信息和操作信…

基于Web智慧油库三维可视化管理系统

油库是协调原油生产、原油加工、成品油供应及运输的纽带&#xff0c;是国家石油储备和供应的基地&#xff0c;它对于保障国防和促进国民经济高速发展具有相当重要的意义。 建设背景 石油作为重要的战略资源&#xff0c;关系着国家安全和人民生活。油库是石油能源供应链中的关…

总结886

学习目标&#xff1a; 月目标&#xff1a;6月&#xff08;张宇强化10讲&#xff0c;专业课&#xff0c;背诵15篇短文&#xff0c;考研核心词过三遍&#xff09; 周目标&#xff1a;1800线性代数部分并完成错题记录&#xff0c;英语背3篇文章并回诵&#xff0c;检测&#xff0…

SpringCloud_微服务基础day1(走进微服务,认识springcloud,微服务(图书管理)项目搭建(一))

官方网站&#xff1a;柏码 - 让每一行代码都闪耀智慧的光芒&#xff01; (itbaima.net) p1:前言&#xff0c;走进微服务 注意&#xff1a;此阶段学习推荐的电脑配置&#xff0c;至少配备4核心CPU&#xff08;主频3.0Ghz以上&#xff09;16GB内存&#xff0c;否则卡到你怀疑人生…

ABB Drive Composer Pro 2.8.1 Crack

Drive Composer 是 ABB 通用架构驱动器的启动和维护工具。该工具用于查看和设置驱动器参数&#xff0c;以及监控和调整过程性能。 Drive Composer入门版提供了设置参数、基本监控、从 PC 对驱动器进行本地控制以及事件记录器处理等基本功能。 Drive Composer pro是成熟的调试和…

deepin安装docker和pytorch

title: deepin安装docker和pytorch date: 2023-06-01 17:28:58 tags: [linux, torch,docker] deepin安装docker和pytorch 总体的流程图大致如下&#xff0c;首先是安装linux&#xff0c;这个直接跳过&#xff0c;接下来就是安装docker&#xff0c;之后&#xff0c;安装docker之…

spring cloud搭建(eureka)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习新东西是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习…

再识openmmlab,用mmDeploy实现部署的前期需要了解一些内容

OpenMMLab 是一个用于学术研究和工业应用的开源算法体系&#xff0c;于2018年年中开始&#xff0c;由 MMLab&#xff08;香港中文大学多媒体实验室&#xff09;和商汤科技联合启动。 如果第一接触的话&#xff0c;还是建议参考官方环境配置教程&#xff1a;Windows 环境配置 -…

OpenGL超级宝典第八章学习笔记:基元处理之曲面细分

前言 本篇在讲什么 OpenGL蓝宝书第八章学习笔记之曲面细分 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻…

有道云笔记也挺速度,也搞了个AI助手,能抗衡Notion AI?

前言 小编平时做技术笔记的时候&#xff0c;经常使用到的软件就是有道云笔记&#xff0c;最近无意间发现&#xff0c;笔记编写的页面中&#xff0c;竟然集成了AI助手&#xff01;网易有道可真是低调&#xff01;毕竟最近AI圈大火&#xff0c;竟然没有蹭一波热度&#xff0c;直…

决策树理论

这个文本讨论了决策树模型中的基尼系数。当数据集的所有数据属于同一类时&#xff0c;基尼系数为0&#xff0c;因为此时无需进行分类&#xff0c;已经属于同一类别。因此&#xff0c;选项B是正确的。 决策树是一种用于分类和预测的机器学习模型。基尼系数是衡量数据集纯度的指标…

苹果服务端通知v2处理(AppStore Server Notifications V2)

苹果服务端通知v2处理 关键词: App Store Server Notifications V2、Python源码、苹果订阅、JWS、x5c、JSON WEB TOKEN 背景 最近要接入苹果订阅功能&#xff0c;调研后发现订阅生命周期内的状态变更是通过苹果服务端通知返回的(什么时候普通内购也能加上减少掉单的概率)&am…

Qt在MySQL中存储音频文件

一、在存储音频视频等大文件时需要以二进制文件进行存储&#xff0c;首先需要了解mysql存储二进制文件的字段类型以及大小&#xff1a; 需要创建数据库中的图片类型为&#xff1a;二进制mediumblob类型&#xff0c;&#xff08; TinyBlob 最大 255 Blob 最大 65K MediumBlob …

基于区域的图像分割

文章目录 基于区域的图像分割基本原理常用的算法实现步骤示例代码结论 基于区域的图像分割 基于区域的图像分割是数字图像处理中常用的一种方法&#xff0c;它通过将图像中的像素分配到不同的区域或对象来实现图像分割的目的。相比于基于边缘或阈值的方法&#xff0c;基于区域…

“智慧赋能 强链塑链”—— 汽车行业供应链管理数字化应用探讨

01车企供应链数字化的必要性 汽车供应链是一个复杂的系统&#xff0c;很多汽车企业因为供应链管理不当&#xff0c;造成资源浪费、成本高、客户满意度低等一系列问题&#xff1b;而汽车行业规模技术门槛高、配合协同复杂的特性&#xff0c;决定了其供应链缺口无法在短时间内填…

结构体大小的计算

结构体计算要遵循字节对齐原则。 结构体默认的字节对齐一般满足三个准则&#xff1a; 结构体变量的首地址能够被其最宽基本类型成员的大小所整除&#xff1b;结构体每个成员相对于结构体首地址的偏移量&#xff08;offset&#xff09;都是成员大小的整数倍&#xff0c;如有需…
最新文章