【数据结构】哈希经典应用:位图——[深度解析](8)

前言

大家好吖,欢迎来到 YY 滴 数据结构 系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁
主要内容含:
在这里插入图片描述

欢迎订阅 YY滴 数据结构 专栏!更多干货持续更新!以下是传送门!

目录

  • 一.位图的基本概念
  • 二.位图的原理
  • 三.位图(bitset)的代码实现(逐过程解读)
    • 【1】位图的文档查看
    • 【2】把X映射的那个标记成1——对应biteset中的set
    • 【3】把X映射的那个标记成0——对应biteset中的reset
    • 【4】判断某位是1还是0——对应biteset中的test
    • 【5】位图的完整实现
  • 四.位图的经典应用场景
    • 【※】对数据大小&转换的基本概念
    • 【1】给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?
    • 【2】给定100亿个整数,设计算法找到只出现一次的整数
    • 【3】位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
    • 【4】给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集?

一.位图的基本概念

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

二.位图的原理

  • 哈希—— 直接定址法
  • 例:
    在这里插入图片描述
  • 在实际场景中,我们的机器一般是 小端机(从左到右,从大到小排布)
  • 所以真正的场景一般如下:
    在这里插入图片描述
  • 小端机性质 证明:
    在这里插入图片描述

三.位图(bitset)的代码实现(逐过程解读)

【1】位图的文档查看

  • 我们可以重点关注红圈圈出的三个位图常用函数
    在这里插入图片描述

【2】把X映射的那个标记成1——对应biteset中的set

在这里插入图片描述

【3】把X映射的那个标记成0——对应biteset中的reset

在这里插入图片描述

【4】判断某位是1还是0——对应biteset中的test

在这里插入图片描述

【5】位图的完整实现

#include<vector>

namespace bit
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_a.resize(N / 32 + 1);//位图的初始化,确定分为多少块
		}

		// x映射的那个标记成1
		void set(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

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

		// x映射的那个标记成0
		void reset(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

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

		bool test(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;

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

四.位图的经典应用场景

【※】对数据大小&转换的基本概念

  • 1G =1024 MB=10241024 BK=10241024*1024 Byte= 2^30 byte = 10亿+ byte
  • 例:我们判断40亿个整数需要多少G呢?
    分析:40亿个int,160亿byte,根据10亿byte对应1G,160亿byte对应16G

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

  • 分析:常规思路是遍历/排序+二分查找
  • 遍历的时间复杂度是O(N),排序(O(NlogN))+二分查找 logN
  • 显然对于40亿无符号整数来说,需要占用16G,占用资源过于庞大,不妥
  • 快速判断在不在,显然是位图经典场景,利用位图解决:
  • 数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:
    在这里插入图片描述

【2】给定100亿个整数,设计算法找到只出现一次的整数

  • 分析:我们可以用两个位图来控制,我们可以这样设计
    在这里插入图片描述
  • 代码展示设计思路如图所示:
template<size_t N>
	class twobitset
	{
	public:
		void set(size_t x)
		{
			// 00 -> 01
			if (!_bs1.test(x) && !_bs2.test(x))
			{
				_bs2.set(x);
			} // 01 -> 10
			else if (!_bs1.test(x) && _bs2.test(x))
			{
				_bs1.set(x);
				_bs2.reset(x);
			}
			// 本身10代表出现2次及以上,就不变了
		}

		bool is_once(size_t x)
		{
			return !_bs1.test(x) && _bs2.test(x);
		}
	private:
		bitset<N> _bs1;
		bitset<N> _bs2;
	};

【3】位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

  • 此题的设计思路与上面的【2】基本一致,设计上要稍作改动:
    在这里插入图片描述
  • 代码展示设计思路如图所示:
template<size_t N>
	class twobitset
	{
	public:
		void set(size_t x)
		{
			// 00 -> 01
			if (!_bs1.test(x) && !_bs2.test(x))
			{
				_bs2.set(x);                        //出现一次
			} // 01 -> 10
			else if (!_bs1.test(x) && _bs2.test(x))
			{
				_bs1.set(x);
				_bs2.reset(x);                    //出现两次
			}// 10 -> 11
			else if (_bs1.test(x) && !_bs2.test(x))
			{
				_bs2.set(x);                      //出现三次
			}
			// 此外代表出现3次及以上,就不变了
		}

		bool max_two(size_t x)
		{
			return (_bs1.test(x) && !_bs2.test(x))||(!_bs1.test(x) && _bs2.test(x));   //10 或者 01
		}
	private:
		bitset<N> _bs1;
		bitset<N> _bs2;
	};

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

  • 分析:
  • 第一种思路是:把其中一个文件存入位图,遍历另一个文件元素,将问题转变成"在不在"问题
  • 问题缺陷: 这种问题存在去重问题,即多次重复(下图中,交集明明只有一个3,但是会出现多个重复的3交集)
    在这里插入图片描述
  • 分析:
  • 第二种思路是:将两个文件映射到两个位图中去(实现去重)
  • 如果相对应的位置都是1(满足相&为1),则此元素就在交集中

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

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

相关文章

ETLCloud详解,如何实现最佳实践及问题排查

ETLCloud介绍 ETLCloud是新一代全域数据集成平台&#xff0c;领先于市场同类产品的数据集成平台(DataOps)&#xff0c;只需单击几下即可完成数据清洗转换、传输入仓等操作&#xff0c;具备高效、智能、一站式的全域数据集成优势&#xff0c;如&#xff1a; 毫秒级实时数据同步 …

《PySpark大数据分析实战》-06.安装环境准备

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

马斯克回应聊天机器人 Grok 抄 ChatGPT 作业;Figma 推出宏编程键盘丨 RTE 开发者日报 Vol.105

开发者朋友们大家好&#xff1a; 这里是「 RTE 开发者日报 」&#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

解决ps找不到MSVCP140.dll的5种方法,完美解决

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到MSVCP140.dll”。这个问题通常出现在安装Adobe Photoshop&#xff08;简称PS&#xff09;时。MSVCP140.dll是Microsoft Visual C 2015 Redistributable的一个组件&#xff0c;它提供…

Openlayers 加载 Geoserver 图层以及范围过滤

Openlayers 加载 Geoserver 图层以及范围过滤 范围过滤核心代码完整代码&#xff1a;在线示例 Openlayers 加载 Geoserver 图层&#xff0c;除了会遇到属性条件查询需求&#xff0c;还经常遇到空间查询&#xff0c;这里介绍一些范围查询。 其实就是利用 Geoserver 的 CQL_FILT…

HarmonyOS应用程序框架

应用程序入口—UIAbility的使用 UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。 每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。 …

深入理解Dubbo-8.Dubbo的失败重试设计

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

搭建Tomcat调试环境并分析CVE-2017-12615

准备 下载存在漏洞版本tomcat&#xff0c;这里下的是8.0.45 https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.45/ 可执行文件和源码都需要下载 用idea打开源码文件&#xff0c;然后将java目录设置为源码目录 配置一下jdk 转成maven项目 添加一些依赖 <dependencie…

DS冲刺整理做题定理(二)线性表、栈、队列的套路

继续归纳套路&#xff0c;做题练习非常重要&#xff0c;王道的基本上足够了&#xff0c;学有余力可以做一下数据结构1800~ DS冲刺整理做题定理&#xff08;一&#xff09;二叉树专题https://blog.csdn.net/jsl123x/article/details/134949736?spm1001.2014.3001.5501 目录 一…

复旦微固化流程

生成boot.bin 如图所示&#xff0c;psoc下的create boot image&#xff0c;选择文件配置路径output bif&#xff0c;任意命名 点击右侧add&#xff0c;分别添加三部分 1.编译FSBL工程后SDK\system_platform\FSBL\Debug\Exe路径下的FSBL.out 2.PL侧的bit文件 3.编译工程后SDK\sy…

1.【Multisim仿真】数电模电学习,仿真软件的初步使用

学习计划路径&#xff1a; >Multisim电路仿真软件熟练掌握 >数字电路基础课程 >逻辑电路设计与应用 >熟练掌握存储器、脉冲波形发生器、D/A和A/D转换器原理 >基本元器件熟练掌握 >晶体管放大电路及负反馈放大电路 >集成运算放大器设计 >电压变电流电路…

Springboot整合阿里巴巴SMS

前提条件 要确保用户有这个权限 还要确保组要有这个权限 讲反了要先保证组有这个权限然后保证用户有这个权限&#xff0c;然后就可以使用这个用户的权限的key来调取api了 申请资质、签名等 申请资质 点击这个进入声请就可以了然后等2个小时左右就可以通过了 申请签名 这个是为…

实操Nginx(4层代理+7层代理)+Tomcat多实例部署,实现负载均衡和动静分离

目录 前言 一、tomcat多实例部署 步骤一&#xff1a;先安装jdk&#xff0c;设置jdk的环境变量&#xff0c;验证是否安装完成&#xff08;192.168.20.8&#xff09; 步骤二&#xff1a;安装tomcat&#xff08;192.168.20.18&#xff09; 步骤三&#xff1a;安装tomcat多实例…

Python数据科学视频讲解:Python保留字与标识符

2.6 Python保留字与标识符 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.6节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据…

VPN 在网络安全中的应用

虚拟专用网络&#xff08;Virtual Private Network&#xff0c;VPN&#xff09;是指利用不安全的公共网络如 Internet 等作为传输媒介&#xff0c;通过一系列的安全技术处理&#xff0c;实现类似专用网络的安全性能&#xff0c;保证重要信息的安全传输的一种网络技术。 1&#…

【网络通信原理之套接字】

目录 概念 分类 数据报套接字&#xff1a;使用传输层UDP协议 流套接字&#xff1a;使用传输层TCP协议 原始套接字 Socket编程注意事项 前言&#xff1a;本文主要介绍了在什么是套接字及在Java中套接字是什么&#xff0c;和在套接字编程的注意事项。 概念 Socket套接…

轮转数组00

题目链接 轮转数组 题目描述 注意点 使用空间复杂度为 O(1) 的 原地 算法解决这个问题 解答思路 本题有多种思路&#xff0c;一种是复制nums数组&#xff0c;然后将k个位置后的值赋值给当前位置即可&#xff0c;但是空间复杂度为O(n)还有一种思路是先将整个数组进行翻转&a…

参数学习——糖果问题(人工智能期末复习)

之前看了好久都不知道这题咋写&#xff0c;后来看了这篇机器智能-高频问题&#xff1a;糖果问题&#xff0c;大概看明白了&#xff0c;其实主要围绕着这两个公式 光看公式也看不懂&#xff0c;还是要结合题目来 己知有草莓味和酸橙味两种类型的糖果&#xff0c;分别放入5种不同…

【FPGA/verilog -入门学习10】verilog 查表法实现正弦波形发生器

0&#xff0c;需求 用查找表设计实现一个正弦波形发生器 寻址的位宽是10位&#xff0c;数据量是1024个&#xff0c;输出的数据是16位 1&#xff0c;需求分析 数据量是1024个&#xff1a; x linspace(0,2*pi,1024) 输出数据是16位: y范围&#xff1a;0~2^16 -1 0~65535…

Docker部署Mysql5.7x和Myslq8.x

Docker部署Mysql5.7x和Myslq8.x 文章目录 1.部署mysql5.7.x2.部署mysql8.x3.创建用户授权及远程登录3.1 mysql5.7创建用户授权及远程登录3.2 mysql8创建用户授权及远程登录 4.总结 1.部署mysql5.7.x 在D盘下的mysql目录下新建如下目录&#xff1a; D:\mysql\conf\my.cnf内容如下…
最新文章