当前位置: 首页 > news >正文

【【哈希应用】位图/布隆过滤器】

位图/布隆过滤器

  • 位图
    • 位图概念
    • 位图的使用
    • 位图模拟实现
  • 布隆过滤器
    • 布隆过滤器概念
    • 布隆过滤器的使用
    • 布隆过滤器模拟实现
  • 位图/布隆过滤器应用:海量数据处理
    • 哈希切分

位图

位图概念

计算机中通常以位bit为数据最小存储单位,只有0、1两种二进制状态,这决定了位可以用来保存某一项条件yes/no的信息,且这种方式是占用系统内存最小的方式。因此,C++中标准库提供bitset类,以位bit为最小单位,存储数据,主要用于提供位级别的操作。

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

位图的使用

初始化bitset,初始化同时给定bit的个数n在这里插入图片描述

bitset<16> foo;
bitset<16> bar(0xfa2);
bitset<16> baz("0101111001"); //从右往左读取,如果字符串长度小于n位数,补0
foo: 0000000000000000
bar: 0000111110100010
baz: 0000000101111001

bitset操作汇总
在这里插入图片描述

位图模拟实现

template<size_t N>
class bitset {bitset(){_bt.resize(N / 8 + 1,0);}//将x位设位1void set(size_t x){size_t i = x / 8;size_t j = x % 8;_bt[i] |= (1 << j);}//将x位设位0void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bt[i] &= ~(1 << j);}//查询x在不在bool test(size_t x){size_t i = x / 8;size_t j = x % 8;return _bt[i] & (1 << j);}
private:vector<char> _bt;
};
//海量数据处理时
void BitSetTest()
{// 开出42亿9千万个比特位bitset<-1> bs1;	bitset<0xffffffff> bs2;
}

布隆过滤器

布隆过滤器概念

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

与位图的区别:
布隆过滤器:布隆过滤器主要用于快速地判断一个元素是否可能存在于数据集合中。可能存在一定的误判率
位图:位图主要用于精确地判断一个整数是否存在于集合中。它可以不会出现误判

在这里插入图片描述

布隆过滤器的使用

初始化
布隆过滤器使用一个长度为m的位图,并初始化所有位为0。同时,需要选择k个不同的哈希函数。

插入
当要将一个元素加入到布隆过滤器时,对该元素进行k次哈希计算,得到k个哈希值(通常是整数)。然后将位数组中对应的k个位置设置为1。
在这里插入图片描述

查询
布隆过滤器进行k次哈希计算,得到k个哈希值。
若其中有任何一个位置为0,则可以确定该元素一定不存在于布隆过滤器中;否则,可能存在(这里存在着一定的误判率,因不同的元素可能存在相同的哈希值,导致位图中相同位置表示了不同的元素存在情况)
在这里插入图片描述
删除
布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
优化:将布隆过滤器中的每个bit位扩展成一个小的计数器,插入元素时,哈希函数计算后为k个位置,给该位置的计数器+1,删除元素时,元素相应位置计数器-1,通过多占用几倍存储空间的代价来增加删除操作。

注意事项:

哈希函数的选择:哈希函数应该能够均匀地分布哈希值,以最大程度减少冲突的可能性。
位数组的大小:位数组的长度m和哈希函数的个数k会直接影响布隆过滤器的误判率。通常情况下,m的大小与预期存储元素数量和容忍的误判率有关。
误判率:布隆过滤器存在一定的误判率,即可能判断某个元素存在于布隆过滤器中,但实际上并不存在。这是由于不同元素在位数组上可能发生冲突的原因。

布隆过滤器模拟实现

template<size_t N,size_t X = 5,class K = string,
class HashFunc1 = BKDRHash,
class HashFunc2 = APHash,
class HashFunc3 = DJBHash>
class BloomFilter
{
public:void Set(const K& key){size_t len = X*N;size_t index1 = HashFunc1()(key) % len;size_t index2 = HashFunc2()(key) % len;size_t index3 = HashFunc3()(key) % len;_bs.set(index1);_bs.set(index2);_bs.set(index3);}bool Test(const K& key){size_t len = X*N;size_t index1 = HashFunc1()(key) % len;if (_bs.test(index1) == false)return false; //准确的size_t index2 = HashFunc2()(key) % len;if (_bs.test(index2) == false)return false;  //准确的size_t index3 = HashFunc3()(key) % len;if (_bs.test(index3) == false)return false;  //准确的return true;  // 存在误判的}// 不支持删除,删除可能会影响其他值。void Reset(const K& key);
-private:bitset<X*N> _bs;

位图/布隆过滤器应用:海量数据处理

位图的应用

快速查找某个数据是否在一个集合中

1.给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】
解答:
1G=2^30=10亿bytes
40亿个int=160亿bytes=16G
数据量非常大,占用内存空间高,用位图可以减少占用内存空间
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:

在这里插入图片描述

2.给定100亿个整数,设计算法找到只出现一次的整数?
用两个位图表示,可以表示的组合有:

组合出现次数
000
011
102
113次以上

统计位图中存的是01的数即为所求

求两个集合的交集、并集

3.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
初始思路:一个文件所有值映射,读取另一个文件,判断在不在
问题:文件中可能存在多个相同的元素,得出的交集需要去重,耗费时间。
优化:两个文件两个位图,对应位置&运算,结果为1的该位置代表的元素是交集

操作系统中磁盘块标记

布隆过滤器应用
在这里插入图片描述
给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?给出精确算法
精确算法:
假设每个query占30个字节,则上面每个文件有3000亿字节==300G,文件很大,我们可以先将它们分成若干小文件,每个小文件之间找交集。
我们使用哈希切割来分割文件。
在这里插入图片描述
这样,相同的query一定进入标号相同的小文件。我们只需分别求两个标号相同小文件的交集。接下来,用set找交集,读出Ai,放到set,读Bi看在不在set,不在则删去。

哈希切分

哈希切分在数据库和分布式系统中经常被使用。以下是一些常见的情况,可以考虑使用哈希切分:

1.数据库分片:当数据库数据量巨大而单个数据库服务器无法承载时,可以将数据划分成多个分片,并使用哈希函数将数据分配到不同的分片中。这样可以提高数据库的可扩展性和性能。

2.负载均衡:在分布式系统中,使用哈希切分可以实现负载均衡。根据请求的特定属性(如客户ID、请求URL等),通过哈希函数计算得到一个标识符,然后利用该标识符选择相应的服务器来处理请求,从而使负载分布更加均匀。

3.分布式缓存:在分布式缓存系统中,使用哈希切分可以将数据分散存储到多个缓存节点中,从而提高缓存容量和读取性能。通过哈希函数计算数据的键值,然后将数据存储到相应的节点上。

需要注意的是,在使用哈希切分时,要确保哈希函数具有良好的均匀性和随机性,以避免数据倾斜和热点问题。此外,由于哈希切分可能引入数据迁移和一致性问题,需要谨慎设计和实施。

相关文章:

【【哈希应用】位图/布隆过滤器】

位图/布隆过滤器 位图位图概念位图的使用位图模拟实现 布隆过滤器布隆过滤器概念布隆过滤器的使用布隆过滤器模拟实现 位图/布隆过滤器应用&#xff1a;海量数据处理哈希切分 位图 位图概念 计算机中通常以位bit为数据最小存储单位&#xff0c;只有0、1两种二进制状态&#x…...

OpenCV学习笔记

一、OpenCV基础 &#xff08;一&#xff09;图像的读取、显示、创建 https://mp.weixin.qq.com/s?__bizMzA4MTA1NjM5NQ&mid2247485202&idx1&sn05d0b4cd25675a99357910a5f2694508&chksm9f9b80f6a8ec09e03ab2bb518ea6aad83db007c9cdd602c7459ed75c737e380ac9c3…...

idea 一键部署jar包

上传成功...

16、SpringCloud -- 常见的接口防刷限流方式

目录 接口防刷限流方式1:隐藏秒杀地址需求:思路:代码:前端:后端:测试:总结:方式2:图形验证码1、生成图形验证码需求:思路:代码:前端:后端:测试:2、校验验证码需求:思路:代码:...

Typora(morkdown编辑器)的安装包和安装教程

Typora&#xff08;morkdown编辑器&#xff09;的安装包和安装教程 下载安装1、覆盖文件2、输入序列号①打开 typora &#xff0c;点击“输入序列号”&#xff1a;②邮箱一栏中任意填写&#xff08;但须保证邮箱地址格式正确&#xff09;&#xff0c;输入序列号&#xff0c;点击…...

服务器不稳定对网站有什么影响

世界上最远的距离&#xff0c;不是树枝无法相依&#xff0c;而是相互了望的星星&#xff0c;却没有交汇的轨迹。 现代技术的进步&#xff0c;导致了人与人之间距 离的消除&#xff0c;直播行业的快速发展的影响和渗透进如今的日常生活&#xff0c;为人们在遥远的距离相见与互诉…...

py实现surf特征提取

import cv2def main():# 加载图像image1 cv2.imread(image1.jpg, cv2.IMREAD_GRAYSCALE)image2 cv2.imread(image2.jpg, cv2.IMREAD_GRAYSCALE)# 创建SURF对象surf cv2.xfeatures2d.SURF_create()# 检测特征点和描述符keypoints1, descriptors1 surf.detectAndCompute(imag…...

MS39233三个半桥驱动器可兼容TMC6300

MS39233 是一款低压三个半桥驱动器。可兼容 TMC6300&#xff08;功能基本一致&#xff0c;管脚不兼容&#xff09;。它可应用于低电压及电池供电的运动控制场合。并且内置电荷泵来提供内部功率 NMOS 所需的栅驱动电压。 MS39233 可以提供最高 2.8A 的峰值电流&#xff0c;其功率…...

09、SpringCloud -- 利用redis的原子性控制高并发请求访问到service层、本地标识

目录 利用redis的原子性控制请求问题:需求:思路什么是原子性的操作?代码思路:代码:工具类依赖SeckillGoodControllerSeckillOrderInfoController测试:本地标识的分析和实现问题:需求:思路:代码:测试:利用redis的原子性控制请求 利用redis的原子性控制人数请求访问到…...

竞赛选题 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…...

基于深度学习网络的美食检测系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 % 图像大小 image_size [224 224 3]; num_classes size(VD,2)-1;% 目标类别数量…...

人工智能基础_机器学习006_有监督机器学习_正规方程的公式推导_最小二乘法_凸函数的判定---人工智能工作笔记0046

我们来看一下公式的推导这部分比较难一些, 首先要记住公式,这个公式,不用自己理解,知道怎么用就行, 比如这个(mA)T 这个转置的关系要知道 然后我们看这个符号就是求X的导数,X导数的转置除以X的导数,就得到单位矩阵, 可以看到下面也是,各种X的导数,然后计算,得到对应的矩阵结…...

【MongoDB】Windows 安装MongoDB 6.0

一、下载安装包 安装包下载地址https://www.mongodb.com/try/download/community这里我选择的是 二、解压并安装 1、解压 这里我将压缩包解压到了D盘&#xff0c;并重命名成了mongodb&#xff0c;解压后的目录如下&#xff1a; 2、创建配置文件 在D:\mongodb下新建conf目录…...

DM8 Dokcer镜像更新后远程无法jdbc连接问题

背景&#xff1a;原来官网下的dm8docker镜像有效期只有两个星期&#xff0c;问他们商务申请了新的dm8镜像&#xff0c;准备简单升级一下镜像再引入原来的database 先说结论&#xff1a;jdbc驱动要更新 官网dm8驱动链接地址 原来的tag镜像 dm8_single:v8.1.2.128_ent_x86_64…...

AI:39-基于深度学习的车牌识别检测

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…...

软考 系统架构设计师系列知识点之系统架构评估(1)

所属章节&#xff1a; 第8章. 系统质量属性与架构评估 第2节. 系统架构评估 1. 概述 系统架构评估是在对架构分析、评估的基础上&#xff0c;对架构策略的选取进行决策。它利用数学或逻辑分析技术&#xff0c;针对系统的一致性、正确性、质量属性、规划结果等不同方面&#x…...

Spark UI中Shuffle dataSize 和shuffle bytes written 指标区别

背景 本文基于Spark 3.1.1 目前在做一些知识回顾的时候&#xff0c;发现了一些很有意思的事情&#xff0c;就是Spark UI中ShuffleExchangeExec 的dataSize和shuffle bytes written指标是不一样的&#xff0c; 那么在AQE阶段的时候&#xff0c;是以哪个指标来作为每个Task分区大…...

Java——Map.getOrDefault方法详解

Java——Map.getOrDefault方法详解 Map.getOrDefault(Object key, V defaultValue)是Java中Map接口的一个方法&#xff0c;用于获取指定键对应的值&#xff0c;如果键不存在&#xff0c;则返回一个默认值。 该方法的签名如下&#xff1a; V getOrDefault(Object key, V defau…...

银河集团香港优才计划95分获批案例展示!看看是如何申请的?

银河集团香港优才计划95分获批案例展示&#xff01;看看是如何申请的&#xff1f; 今天来分享一则银河集团香港优才计划获批案例&#xff01;客户本科学历非名校、从事业务支援及人力资源行业&#xff0c;优才打分95分&#xff0c;这个条件可能在很多人的印象里&#xff0c;会觉…...

Python class中以`_`开头的类特殊方法

在学基础的时候没学到过&#xff08;可能见过但是又忘了&#xff09;&#xff0c;在学习深度学习项目的时候遇见了很多&#xff1b; 以论文Multi-label learning from single positive label为例&#xff1b; 这些方法都是程序自行调用的&#xff0c;不需要&#xff08;也不可以…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...