哈希的应用->位图

news2024/11/26 18:45:26

ps:左移位并不是向左移动位,而是低数据位向高数据位挪动

位图(主要接口,set(size_t)标识、reset(size_t)取消、test(size_t) 查看

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

这么多的数据根本无法在内存中存储,所以,将他们放进set,map中这是不切实际的。

遍历一遍数据,也许可以,但是如果再来一个查找值,难道还要再遍历一遍吗?再来再遍历?

注意审题:

  1. 我们会发现,我们并不需要将数据存储起来,我们只是需要知道,他是否存在于这40亿个数中,所以我们只需要判断40个亿中有没有该数。
  2. size_t类型的数据范围是0~40亿多,如果普通的哈希创建size_t类型的数组来标识下标对应的是否重载,我们需要4*40亿个字节的空间=>16个G的内存,机器不说能不能存下,就是是64位存下了,那么我们的操作系统怎么办???

构造位图bit_set

成员变量:

template <size_t N>
class bitset
{	
//........
private:
	vector<char> _map;//图的意思
}

注意我们其实只是想知道是否存在,标识40亿个数据罢了,并不是真的要存储40亿个数据,所以我们使用计算机存储单位最小的类型比特位来存储数据,应为size_t类型范围的最小是0,最大是42亿多,所以这道题我们需要直接创建42亿个比特位来存储,数组下标的位置映射元素是否存在该数,1标识存在,0标识不存在。注意我们无法直接创建比特类型的数组,我们需要创建其他类型,然后位处理比特位。所以我们创建char类型的数组来映射比特数组。

所以我们的数组只需要开char[40亿/8]大小的数组(一个char可以标识8个数据)

这样我们存在的问题,就不需要考虑类型了,只需要考虑个数问题。

构造函数代码

bitset()
{
	_bits.resize(N/8+1,0);//将所有位初始化为0
}

标识数据位set(size_t)

我们需要把这40亿个size_t 数据标识到位图中。

例:我们将40亿中的26数据标识到位图中

2步走

  1. 寻找需要标识的位置
  2. 标识比特位为1

寻找数据标识位: 

我们确定了26数据存储在map[3]的第二个比特位,

修改标记数据位为1:

我们现在需要把这个位置的bite位给标记为1,该如何呢?

我们需要对该位置继续位操作,

使用位运算符号|对图中该位置改为1,并且其他位置不动,所以我们需要一个数据同位为1,其他位为0,与图的该char类型元素进行逻辑或运算, 

 

这样,该位无论是什么在或上1都被标识为1,其他位或上0先前是什么,现在依旧是什么

这样我们的数据就标识完毕。

代码:

void bit_set::set(size_t x)
{
	int loction = x / 8;
	int bitloction = x % 8;
	char  flag = 1;
	flag = flag << bitloction;
	_bits[loction] |= flag;
}

取消标识位( reset() )

假设我们把刚刚set的数据26   reset()取消掉

2步走

  1. 寻找需要标识的位置
  2. 标识比特位为0

寻找数据标识位

首先也是寻找位和我们之前set()操作是一样的,

数据/8得:map得下标元素,

数据%8得:标识该元素得比特位

所以我们跳过寻找逻辑。

修改标记数据位为0:

修改得逻辑其实和之前是一样的,但是我们现在需要的是将该位置标识为0,其他位置不变,

需要对数据标记位逻辑与0,保证该其位置标识改变为0(不论操作标识位是什么都改为0)

需要对其它位置逻辑与1,保证其他位置标识不受到改变为0(不论其他标识位是什么,都不能改变)

 然后也是对数据1进行位运算操作~直接上图

这样,该位无论是什么在与上0都被标识为0,其他位与上1先前是什么,现在依旧是什么

这样我们的数据就取消标识。

代码:

void reset(size_t x)
{
	int loction = x / 8;
	int bitloction = x % 8;
	char flag = 1;
	flag = flag << bitloction;
    flag=(~flag);
	_bits[loction] &= flag;
}

查看数据是否已标识 test()

现在我们并不知道该26数据是否在位图中。

2步走

  1. 寻找需要标识的位置
  2. 查看标识位

寻找数据标识位

首先也是寻找位和我们之前set()操作是一样的,

数据/8得:map得下标元素,

数据%8得:标识该元素得比特位

所以我们跳过寻找逻辑。

查看该位置是否为被标识

获取到了,我们只需要找到该位数据存不存在并不怎么样,所以我们只需要真假,不关心是具体数据是什么。

所以我们将该char元素其他的比特位置0,其用比特位1与其按位与,检查其是否存在。

所以我们需要map[3]:10X0 1101  -> 00X0 0000 的数据,获取辅助数据的方法与set()一样。

注意,test实现不可改变map[3]的值,所以保存到一个变量,或者按位与数据返回

代码:

bool test(size_t x)
{
	int loction = x / 8;
	int bitloction = x % 8;
	char flag = 1;
	flag = flag << bitloction;
	return _bits[loction] & flag;
//  bool tmp=_bits[loction] & flag;
//  return tmp;
}

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

1、bitset<-1> _map; 范围开size_t的取值范围 42亿多个比特位

2、_map.set(40亿size_t);  将40亿个数据映射到位图中

3、cout<<_map.test(查找的数据)  查看数据是否在位图中,1就是在,0就是不在 

完成


完整代码:

template <size_t N>
class bitset
{
public:
	bitset()
	{
		_bits.resize(N / 8 + 1, 0);
	}
	void set(size_t x)
	{
		int loction = x / 8;
		int bitloction = x % 8;
		char  flag = 1;
		flag = flag << bitloction;
		_bits[loction] |= flag;
	}

	void reset(size_t x)
	{
		int loction = x / 8;
		int bitloction = x % 8;
		char flag = 1;
		flag = flag << bitloction;
		_bits[loction] &= (~flag);
	}

	bool test(size_t x)
	{
		int loction = x / 8;
		int bitloction = x % 8;
		char flag = 1;
		flag = flag << bitloction;
		return _bits[loction] & flag;
	}

private:
	vector<char> _bits;
};

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

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

相关文章

做软件测试到底要不要学编程?

乔布斯曾经说过“每个人都应该学习编程&#xff0c;因为它会教你如何思考”&#xff0c;看&#xff0c;乔帮主都觉得所有人都应该学编程&#xff0c;那你说做测试的要不要学&#xff1f;当然要。 作为测试人员&#xff0c;除了上面这个原因&#xff0c;我觉得如果会编程&#x…

Android架构之MVC,MVP,MVVM解析

MVC架构 View&#xff1a;Acitivity(View)、Fragment(View)视图&#xff0c;在android里xml布局转成View后&#xff0c;加载到了Activity/Fragment里了。 Controller&#xff1a;Controller对应着Activity/Fragment&#xff0c;绑定UI&#xff0c;处理各种业务。 Model&#xf…

python接口自动化(三十)--html测试报告通过邮件发出去——中(详解)

简介 上一篇&#xff0c;我们虽然已经将生成的最新的测试报告发出去了&#xff0c;但是MIMEText 只能发送正文&#xff0c;无法带附件&#xff0c;因此我还需要继续改造我们的代码&#xff0c;实现可以发送带有附件的邮件。发送带附件的需要导入另外一个模块 MIMEMultipart。还…

java版电子招标采购系统源码之电子招标采购实践与展望-招标采购管理系统

统一供应商门户 便捷动态、呈现丰富 供应商门户具备内外协同的能力&#xff0c;为外部供应商集中推送展示与其相关的所有采购业务信息&#xff08;历史合作、考察整改&#xff0c;绩效评价等&#xff09;&#xff0c;支持供应商信息的自助维护&#xff0c;实时风险自动提示。…

springboot+MySQL实现4S店车辆管理系统

本系统为了数据库结构的灵活性所以打算采用MySQL来设计数据库&#xff0c;而java技术&#xff0c;B/S架构则保证了较高的平台适应性。本文主要介绍了本系统的开发背景&#xff0c;所要完成的功能和开发的过程&#xff0c;主要说明了系统设计的重点、设计思想。

计算机体系结构基础知识介绍之使用多问题和静态调度来利用 流水线

为了提高处理器的性能&#xff0c;我们需要让每个时钟周期内发出多条指令&#xff0c;而不是只发出一条。这种多发射处理器有三种主要类型&#xff1a; 1. 静态调度的超标量处理器 2. VLIW&#xff08;非常长指令字&#xff09;处理器 3. 动态调度的超标量处理器。 这三种类型的…

lua 请求ftp服务器数据,下载文件

1、装入ftp库 2、调用ftp的get()方法 3、get()方法参数格式&#xff1a; 4、将返回到的数据写入文件中 例如&#xff0c;本次获取专利数据系统 http://patdata1.cnipa.gov.cn/ 的ftp站点数据 local ftp require("socket.ftp")--此处我没填端口号 file,err ftp.g…

findfont: Font family ‘Times New Roman‘ not found.

问题 Linux 使用 matplotlib.pyplot 画图时为了使字体和英文论文中的 Times of Roman 一致&#xff0c;通常会用到如下文本格式 font1 {family: Times New Roman, # x and y labelsweight: normal,size: 16}但在实际使用时会出现如下报警信息&#xff1a; findfont: Font …

element ui 导入模块的封装

导入组件的封装 <template><Modal :visible"visible" title"导入" onSave"onSave" onCancal"closeDialog"><template #default><el-upload ref"upload" class"upload-demo"action"ht…

Scala中使用 break 和 continue

Scala中没有 break 和 continue 关键字&#xff0c;但是我们可以用 Breaks 类提供的相应方法来实现对应功能。 在Java中&#xff0c;break continue return的区别 1、break&#xff1a;break不仅可以结束其所在的循环&#xff0c;还可结束其外层循环&#xff0c;但一次只能结束…

Vulnhub: Hackable:II靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.142 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.142 网站的files目录 ftp存在匿名登录&#xff0c;所在目录为网站的files目录 ftp上传反弹shell 提权 目标根目录下的.ru…

预付费智能水表远程控制系统

预付费智能水表远程控制系统是一种基于物联网技术的智能水表管理系统&#xff0c;它通过远程通信技术和云计算平台&#xff0c;实现了对水表的实时监控、数据采集、费用计算、远程控制等功能。该系统不仅可以提高水务公司的管理效率&#xff0c;还可以为用户提供更加便捷、可靠…

[疑难杂症2023-004]停止服务器自动启动的服务,解决端口占用的问题

本文由Markdown语法编辑器编辑完成。 1. 背景 前段时间&#xff0c;在linux上启动一个目录下的docker-compose.yml中的服务时&#xff0c;遇到了一个3000端口被占用的问题. 凭借经验&#xff0c;一般可能是之前的服务没被正常的停止掉&#xff0c;导致该服务占用的端口未被释…

阿里云——网站建设:动态网站建设(知识点)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 写在前面 课程目标 一.简单搭建动态网站 1.网站搭建类型 &#xff08;1&#xff0…

eclipse4.2.1 juno install SWT 1.7

SWT-windowbuilder-1.7-eclipse4.2.1-juno windows WB_v1.7.0_UpdateSite_for_Eclipse4.2.zip

【ESP32-CAM】20元就能搭建简易Web摄像头

图文步骤 在首选项中&#xff0c;增加网址https://dl.espressif.com/dl/package_esp32_index.json 安装esp32资源包 选择ESP32-CAM开发板 选一个USB-TTL的串口工具&#xff0c;按照图示&#xff0c;RX接U0TXD&#xff0c;TX接U0RXD&#xff0c;GND和5V供电&#xff0c;其中G…

3 2^k-分位数组

作者: 赵晓鹏时间限制: 1S章节: 递归与分治 #include <iostream> #include <algorithm> #include <queue> #include <tuple> #include <stack> #pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast",&quo…

【UGUI学习笔记】渲染层级

文章目录 Camera渲染Canvas渲染Sorting LayerOrder in Layer 图层渲染 Camera渲染 摄像机的渲染层级需要修改Clear Flags属性&#xff0c;这个属性下的四种模式比较复杂&#xff0c;此处只是介绍不同渲染方式下进行的选择。 摄像机的默认模式是Skybox&#xff0c;也就是视距内…

Acwing 850. Dijkstra求最短路 II

Acwing 850. Dijkstra求最短路 II 链接:850. Dijkstra求最短路 II - AcWing题库 /* 题解:堆优化版本的dijkstra 就是优化了 每次寻找当前距离源最近的点的时间 有小顶堆来维护当前为确定的点和源的距离 那么每次找最新确定的点的时候就是堆顶 */ #include<iostream> #i…

阐述kubernetes部署:基础设施安装

基础设施部署 持久卷的建立 请参考&#xff1a;《持久卷的建立》 elasticsearch部署 一、设置远程扩展字典 不使用自定义字典请忽略此步骤 首先更改ES中IK插件的配置&#xff1a; vi/opt/kubernetes/es/IKAnalyzer.cfg.xml 按您的实际设置的秘钥配置secret_value&#xff1a; …