可碧教你C++——位图
本章节是哈希的延申
可碧教你C++——哈希
http://t.csdnimg.cn/3R8TU
一文详解C++——哈希
位图
位图是基于哈希表的原理产生的一种新的container——bitset
基于哈希映射的原理,我们在查找的时候,可以直接去定址到元素的具体位置,然后直接访问该元素。但是如果没有哈希冲突,我们甚至完全不需要检查哈希映射对应的元素是否为我们需要查找的元素,直接判断这个位置有没有元素,便可以知道该元素在不在哈希表里。
而判断某一个位置有没有元素,只需要0和1便可以完成,也就是无论被存储数据的大小,每个数据只需要1个比特位的存储空间,这无疑极大压缩了内存空间。而通过这种方式实现的数据结构,便被称为——位图。
位图的结构
一般来说,我们只有在内存空间不足以解决既有的问题下,才会去考虑缩小数据空间的问题。同样,内存的使用场景一般是在有着海量数据下,我们要对某个数据进行查重,才会使用位图。位图的原理是哈希表,其构成当然离不开数组,实际上位图和普通的哈希表构成几乎相同, 只不过将数组的单元格变成了一个个的比特位。
但是,C++中并无法将单个比特位作为单元格,我们只能通过某种方法间接去访问比特位
例如:我们将每个单元格设为整型int,然后每个整型int具有4字节32个比特位,我们便可以通过相除的方式寻找具体的单元格,再用除余的方式寻找比特位.
这便是位图的最基本的结构:
class bitset
{private:vector<int> _table;//可以是任何模板参数,只需要该参数所占有的比特位//但是最好不要用指针,因为在不同位的电脑上指针的比特位不同
}
位图的访问
位图的访问实际上是对比特位的访问。但是我们很难专门去访问某一个比特位,我们只能采取异或的方法,将其他位全置为0,从而间接访问具体的一位的值。
通过以上两个式子,我们很快就能找到解决方案:
只要构建出一个辅助量,其他位都为0,只有被查找的那一位为1,然后取&,最终得到的结果便只与需要查找的值有关了。如果该值为1,则整个值非0,返回true;如果该值为0,则整个值为0,返回false。
下一个问题便是,如何构建这一个辅助量?这便需要用到移位运算符。
也就是说,我们想访问哪一位,就只需要移位多少位,便可以达成条件。
//查找元素,约等于find
bool test(int key)
{size_t plane = key / 32;//第几辆飞机size_t seat = key % 32;//第几个座位return _table[plane] & (1 << seat);//构建辅助量并&
}
位图的插入和删除
位图的插入和删除,实际上也是考虑如何在不影响其他比特位的情况下,对某一具体比特位的操作。
插入,就是将该位便为1;删除,就是将该位便为0,这里又需要我们使用异或的性质:
于是很容易想到
- 插入的时候,我们使用|,辅助量为其他位全为0,修改位为1
- 删除的时候,我们使用&,辅助量其他位全为1,修改位为0
位图的实现
位图不支持扩容。我们在使用位图的时候,就必须传入位图需要的空间大小
class bitset
{
public:bitset(int n){_table.resize(n);}//将元素设为1,约等于insertvoid set(int key){size_t plane = key / 32;size_t seat = key % 32;_table[plane] |= (1 << seat);}//将元素设为0,约等于erasevoid reset(int key){size_t plane = key / 32;size_t seat = key % 32;_table[plane] &= ~(1 << seat);}//查找元素,约等于findbool test(int key){size_t plane = key / 32;size_t seat = key % 32;return _table[plane] & (1 << seat);}
private:vector<int> _table;
};
布隆过滤器
上面所述的位图都是在不考虑哈希冲突的情况下所实现,但是实际上,哈希冲突是不可能被避免的。 难道必须要在规定没有哈希冲突的情况下,位图才有意义吗?当然不是。我们不妨直面哈希冲突,看看在有哈希冲突的情况下,位图会产生什么影响。
哈希冲突会导致其他与其具有相同哈希映射值的元素,也被视作为存在于哈希表中。
- 如果数据存在,无论该位是否存在冲突,则该位一定为1;
- 如果数据不存在,则该为可能为0,也可能会因其他数据的冲突导致该位为1;
而反过来通过表中的状态判断数据是否存在于表中
- 如果表中存在,无法判断该数据是否存在,因为可能是其他的值产生的1
- 如果表中不存在,则该哈希映射值对应的所有元素一定都不存在
是不是就像大家平时上课签到一样
也就是说,我们可以采用他的准确性——判断数据是否不在表中
最常见的应用场景便是取名查重。我们可以接受一个未被取的名字被视为已经占用,但是不能接收重名,此时采用这种过滤方式,可以在满足条件的情况下尽可能节省空间。
多重过滤
尽管我们可以接受误判,但是我们还是不想有太多类似于科比布莱恩特24这样因误判而导致可取名变少带来的产物,那还有没有其他办法去尽量避免呢?
既然一重过滤会导致误判,那多重过滤,是不是误判就减少了
- 只有三个毕业证都存在,才表示学历是真真正正存在的。
- 而如果其中任何一个毕业证不存在,则表示其学历是伪造的。
我们创建三个位图,每个位图使用不同的哈希映射,当一个数据插入到布隆过滤器时,会映射到三个不同的位置上,每个位图都会产生相应的插入结果。也就是说,只有当三个位图都存在该数据,才表示布隆过滤器存在该数据。 相应的,如果任何一个位图中不存在某个数据,则表示其他位图中该数据的存在时哈希冲突产生的。而因为采用了多种哈希映射,三个位图的哈希冲突完全相同的可能性几乎为0,也就避免了哈希冲突的存在。
class bloom_filter
{private:bitset _hash1;bitset _hash2;bitset _hash3;
}
布隆过滤器的问题
虽然布隆过滤器可以避免插入的哈希冲突,但是还是有这样一个巨大的问题——删除。
我们想删除一个数据,当然是将三个位图中所有对应的数据都删除。但是删除以后,哈希冲突导致的其他数据也被删除了。这种改变是不可逆的,因为我们并不知道到底有多少数据在该位上哈希冲突了。等到判断的时候,因为该数据在某一个表中被误删,导致就算该数据在其他两个表中仍存在,也会被误判为不存在。
所以,布隆过滤器一般是不允许删除的,当然也有解决方法,便是在每个位置上进行引用计数,但是这便舍弃了布隆过滤器节省空间的初衷和优点。
哈希切割
哈希切割不是一个具体的container。哈希切割是利用哈希的思想,对某些问题处理的方法。
假如某个数据库存有海量的数据,一个服务器并没有办法很好处理这些数据,要将这些数据分开到几个不同的服务器进行处理,往往会面临几个需求
- 相同或类似的数据放在同一个服务器中
- 每一个服务器的数据量尽量平均
- 尽量不要浪费空间以减少服务器的数量
此时红黑树等容器便没有办法满足了。尽管一些有序容器可以处理数据的特征,但是因为服务器的分离,红黑树很难去跨设备访问其他数据,所以这里大部分container都会罢工。
在这里,我们就必须采取哈希的思想,通过数据的除余,将除余相同的数据放在同一个服务器中。这样,重复的数据自然因除余相同被归类到了一个服务器里,而类似的数据同样可以通过一些算法分割到相同的服务器中。
相关文章:

可碧教你C++——位图
本章节是哈希的延申 可碧教你C——哈希http://t.csdnimg.cn/3R8TU 一文详解C——哈希 位图 位图是基于哈希表的原理产生的一种新的container——bitset 基于哈希映射的原理,我们在查找的时候,可以直接去定址到元素的具体位置,然后直接访问该…...

2024年虚拟DOM技术将何去何从?
从诞生之初谈起,从命令式到声明式,Web开发的演变之路 Web开发的起源与jQuery的统治 在Web开发的早期阶段,操作DOM元素主要依赖命令式编程。当时,jQuery因其易用性而广受欢迎。使用jQuery,开发者通过具体的命令操作DOM&…...
基于51单片机的恒温淋浴器控制电路设计
标题:基于51单片机的智能恒温淋浴器控制系统设计与实现 摘要: 本论文主要探讨了一种基于STC89C51单片机为核心控制器的恒温淋浴器控制系统的详细设计与实现。系统通过集成温度传感器实时监测水温,结合PID算法精确控制加热元件工作状态&#…...
【redis】redis的bind配置
在配置文件redis.conf中,默认的bind 接口是127.0.0.1,也就是本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接, 这样可以避免将redis服务暴露于危险的网络环境中,防止一些…...

C++ 继承
目录 一、继承的概念及定义 1、继承的概念 2、继承定义 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员 七、复杂的菱形继承及菱形虚拟继承 1、菱形继承 2、虚拟继承 3、例题 八、继承的总结和反思…...

了解ASP.NET Core 中的文件提供程序
写在前面 ASP.NET Core 通过文件提供程序来抽象化文件系统访问。分为物理文件提供程序(PhysicalFileProvider)和清单嵌入的文件提供程序(ManifestEmbeddedFileProvider)还有复合文件提供程序(CompositeFileProvider );其中PhysicalFileProvider 提供对物理文件系统…...

竞赛保研 基于深度学习的人脸性别年龄识别 - 图像识别 opencv
文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计…...
JavaScript音视频,JavaScript简单获取电脑摄像头画面并播放
前言 本章实现JavaScript简单获取电脑摄像头画面并播放的功能 兼容性(不支持Node.js) 需要注意的是,由于涉及到用户的隐私和安全,获取用户媒体设备需要用户的明确同意,并且可能需要在用户的浏览器中启用相关的权限。在某些浏览器中,可能需要用户手动开启摄像头权限。 …...
《JVM由浅入深学习【五】 2024-01-08》JVM由简入深学习提升分享
目录 JVM何时会发生堆内存溢出?1. 堆内存溢出的定义2. 内存泄漏的原因3. 堆内存溢出的常见场景4. JVM参数调优5. 实际案例分析 JVM如何判断对象可以回收1.可达性分析的基本思路2.实际案例3.可以被回收的对象4.拓展, 谈谈 Java 中不同的引用类型? 结语感…...

FastDFS之快速入门、上手
知识概念 分布式文件系统 通过计算机网络将各个物理存储资源连接起来。通过分布式文件系统,将网络上任意资源以逻辑上的树形结构展现,让用户访问网络上的共享文件更见简便。 文件存储的变迁: 直连存储:直接连接与存储…...

Vue 中的 ref 与 reactive:让你的应用更具响应性(中)
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...

【数据库基础】Mysql与Redis的区别
看到一篇不错的关于“Mysql与Redis的区别”的文章,转过来记录下~ 文章目录 一、数据库类型二、运行机制三、什么是缓存数据库呢?四、优缺点比较五、区别总结六、数据可以全部直接用Redis储存吗?参考资料 一、数据库类型 Redis:NOS…...

JVM工作原理与实战(六):类的生命周期-连接阶段
专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类的生命周期 1.加载(Loading) 2.连接(Linking) 3.初始化(Initialization) 4.使用(Using&…...
【OCR】 - Tesseract OCR在Windows系统中安装
Tesseract OCR 在Windows环境下安装Tesseract OCR(Optical Character Recognition)通常包括以下几个步骤: 下载Tesseract 访问Tesseract的GitHub发布页面:https://github.com/tesseract-ocr/tesseract/releases找到适合你操作系…...

YOLOv8改进 | 损失函数篇 | SlideLoss、FocalLoss分类损失函数助力细节涨点(全网最全)
一、本文介绍 本文给大家带来的是分类损失 SlideLoss、VFLoss、FocalLoss损失函数,我们之前看那的那些IoU都是边界框回归损失,和本文的修改内容并不冲突,所以大家可以知道损失函数分为两种一种是分类损失另一种是边界框回归损失,上一篇文章里面我们总结了过去百分之九十的…...
计算机网络试题——填空题(附答案)
在OSI模型中,第一层是____________层。 答案:物理(Physical) TCP协议是一种_____________连接的协议。 答案:面向连接(Connection-oriented) IPv6地址的位数是____________。 答案:1…...

第二证券:股票私募仓位指数创近八周新高
1月8日,A股几大首要指数全线收跌,上证指数收于日内最低点2887.54点,间隔上一年5月份的阶段高点3418.95点现已跌去了15.54%。 不过,虽然商场仍未清晰止跌,私募基金们却现已进场“抄底”。私募排排网最新发布的私募仓位…...
35-javascript基础,引入方式;变量命名规范
html分为三部分;结构html,表现css,行为js;js就是javascript js包含三部分: ECMAScript:简称ES,ES5,ES6核心语法 DOM:获取和操作html元素的标准方法;BOM&am…...

笔试案例2
文章目录 1、笔试案例22、思维导图 1、笔试案例2 09)查询学过「张三」老师授课的同学的信息 selects.*,c.cname,t.tname,sc.score from t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc where t.tidc.cid and c.cidsc.cid and sc.sids…...
【嵌入式-网络编程】vmware中使用UDP广播失败问题
问题描述: 自己在vmware中搭建了2台虚拟机,虚拟机A向虚拟机A和虚拟机B发送广播信息,接收端在虚拟机A和虚拟机B,这个时候,由于没配置sin.sin_addr.s_addr htonl(INADDR_ANY);,而是配置的inet_pton(AF_INET,…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...