【C++哈希应用】位图、布隆过滤器
【C++哈希应用】位图、布隆过滤器
目录
- 【C++哈希应用】位图、布隆过滤器
- 位图概念
- 位图的实现
- 位图改造
- 位图应用总结
- 布隆过滤器
- 布隆过滤器的提出
- 布隆过滤器的概念
- 布隆过滤器的查找
- 布隆过滤器删除
- 布隆过滤器优点
- 布隆过滤器缺陷
作者:爱写代码的刚子
时间:2023.9.30
前言:本篇博客介绍hash应用部分——位图和布隆过滤器,利用位图和布隆过滤器解决一些特定场景的问题。
位图概念
所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比 特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:
位图的实现
template<size_t N>class bitset{public:bitset(){_a.resize(N/32+1);//不要忘了+1,默认初始化成0}void set( size_t x){int i=x/32;int j=x%32;_a[i] |=(1<<j);}void reset(size_t x){int i=x/32;int j=x%32;_a[i] &= (~(1<<j));}bool test(size_t x){int i=x/32;int j=x%32;return _a[i] &(1<<j);}private:vector<int> _a; };
位图改造
用两个位图来测试数据个数
template<size_t N>class twobitset{public:void set(size_t x){//00->01if(!_b1.test(x)&&!_b2.test(x)){_b2.set(x);}//01->10else if(!_b1.test(x)&&_b2.test(x)){_b1.set(x);_b2.reset(x);}}bool is_once(size_t x){return !_b1.test(x)&&_b2.test(x);}bool is_or_above_twice(size_t x){return _b1.test(x)&&!_b2.test(x);}private:bitset<N> _b1;bitset<N> _b2;};
位图应用总结
- 快速查找某个数据是否在一个集合中
- 排序
- 求两个集合的交集、并集等
- 操作系统中磁盘块标记
布隆过滤器
布隆过滤器的提出
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用户看过的所有历史记 录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。 如何快速查找呢?
- 用哈希表存储用户记录,缺点:浪费空间
- 用位图存储用户记录,缺点:不能处理哈希冲突 3. 将哈希与位图结合,即布隆过滤器
布隆过滤器的概念
布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结 构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函 数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间
// 假设布隆过滤器中元素类型为K,每个元素对应5个哈希函数
template<class K, class KToInt1 = KeyToInt1, class KToInt2 = KeyToInt2,class KToInt3 = KeyToInt3, class KToInt4 = KeyToInt4,class KToInt5 = KeyToInt5>
class BloomFilter
{
public:BloomFilter(size_t size) // 布隆过滤器中元素个数 : _bmp(5*size), _size(0){}bool Insert(const K& key){size_t bitCount = _bmp.Size();size_t index1 = KToInt1()(key)%bitCount;size_t index2 = KToInt2()(key)%bitCount;size_t index3 = KToInt3()(key)%bitCount;size_t index4 = KToInt4()(key)%bitCount;size_t index5 = KToInt5()(key)%bitCount;_bmp.Set(index1); _bmp.Set(index2);_bmp.Set(index3);_bmp.Set(index4);_bmp.Set(index5);_size++;}
private:bitset _bmp;size_t _size;// 实际元素的个数
}
布隆过滤器的查找
布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特位一定为1。 所以可以按照以下方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为零,只要有一个为零, 代表该元素一定不在哈希表中,否则可能在哈希表中。
bool IsInBloomFilter(const K& key)
{size_t bitCount = _bmp.Size();size_t index1 = KToInt1()(key)%bitCount;if(!_bmp.Test(index1))return false;size_t index2 = KToInt2()(key)%bitCount;if(!_bmp.Test(index2))return false;size_t index3 = KToInt3()(key)%bitCount;if(!_bmp.Test(index3))return false;size_t index4 = KToInt4()(key)%bitCount;if(!_bmp.Test(index4))return false;size_t index5 = KToInt5()(key)%bitCount;if(!_bmp.Test(index5))
return false; return true; // 有可能在
}
注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。比如:在布隆过滤器中查找"alibaba"时,假设3个哈希函数计算的哈希值为:1、3、7,刚好和其他元素的比特位重叠,此时布隆过滤器告诉该元素存在,但实该元素是不存在的。
布隆过滤器删除
布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
比如:删除上图中"tencent"元素,如果直接将该元素所对应的二进制比特位置0,“baidu”元素也被删除了, 因为这两个元素在多个哈希函数计算出的比特位上刚好有重叠。
一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。
缺陷:
- 无法确认元素是否真正在布隆过滤器中
- 存在计数回绕
布隆过滤器优点
-
增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关
-
哈希函数相互之间没有关系,方便硬件并行运算
-
布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
-
在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
-
数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
-
使用同一组散列函数的布隆过滤器可以进行交、并、差运算
布隆过滤器缺陷
- 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白 名单,存储可能会误判的数据)
- 不能获取元素本身
- 一般情况下不能从布隆过滤器中删除元素
- 如果采用计数方式删除,可能会存在计数回绕问题
附:
一致性哈希
哈希与加密
相关文章:
【C++哈希应用】位图、布隆过滤器
【C哈希应用】位图、布隆过滤器 目录 【C哈希应用】位图、布隆过滤器位图概念位图的实现位图改造位图应用总结布隆过滤器布隆过滤器的提出布隆过滤器的概念布隆过滤器的查找布隆过滤器删除布隆过滤器优点布隆过滤器缺陷 作者:爱写代码的刚子 时间:2023.9…...
Qt 编译纯c的C99的项目, error: undefined reference to `f()‘
把Cpp的后缀该为C是什么样的 尝试引用一个奇门排盘的c程序,在git上找到的叫cqm, 然后总是报错 error: undefined reference to f() 很是郁闷 于是新建了个项目试验一下,终于摸清了需要命名空间。 后来这么写就可以了 a.h namespace XX …...
TensorFlow入门(五、指定GPU运算)
一般情况下,下载的TensorFlow版本如果是GPU版本,在运行过程中TensorFlow能自动检测。如果检测到GPU,TensorFlow会默认利用找到的第一个GPU来执行操作。如果机器上有超过一个可用的GPU,除第一个之外的其他GPU默认是不参与计算的。如果想让TensorFlow使用这些GPU执行操作,需要将运…...
Unity - 实践: Metallic流程贴图 转 Specular流程贴图
文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图,在 unity 中展示:M…...
第三章:最新版零基础学习 PYTHON 教程(第四节 - Python 运算符—Python 逻辑运算符及示例)
运算符用于对值和变量执行操作。这些是执行算术和逻辑计算的特殊符号。运算符运算的值称为操作数。 表中的内容逻辑运算符 逻辑与运算符 逻辑或运算符 逻辑非运算符 逻辑运算符的求值顺序 逻辑运算符 在 Python 中,逻辑运算符用于条件语句(True 或 False)。它们执行逻辑 AN…...
如何做好测试?(三)功能测试 (Functional Testing, FT)
1. 功能测试的详细介绍: 功能测试 (Functional Testing, FT),是一种软件测试方法,旨在验证系统的功能是否按照需求规格说明书或用户期望的方式正常工作。它关注系统的整体行为,以确保各个功能模块和组件之间的交互和集成正确。 …...
Ubuntu-Server-22.04安装桌面+VNC
前提:Ubuntu Server安装好后,ubantu其他版本是否适用这里未知,欢迎大佬们前来评论 一、默认没有图形界面,有时觉得用图形界面操作更简单直接,于是用如下命令安装: 1.更新本地环境 sudo apt-get update s…...
职业规划,什么是职业兴趣 - 我喜欢做什么?
能够在工作岗位上面做出成绩的人,都是结合自身兴趣,对职业进行合理规划的那一类。尤其是步入中年以后,能够创造出巨大价值的人,无一例外都是喜欢自己职业的人。没有将兴趣融入工作的人,只能够忍受默默无闻地活着&#…...
基于Java的高校学生党员发展流程管理系统设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...
【NLP的python库(03/4) 】: 全面概述
一、说明 Python 对自然语言处理库有丰富的支持。从文本处理、标记化文本并确定其引理开始,到句法分析、解析文本并分配句法角色,再到语义处理,例如识别命名实体、情感分析和文档分类,一切都由至少一个库提供。那么,你…...
面试理论篇三
关于异常机制篇 异常描述 目录 关于异常机制篇异常描述 注:自用 1,Java中的异常分为哪几类?各自的特点是什么? Java中的异常 可以分为 可查异常(Checked Exception)、运行时异常(Runtime Exception) 和 错误(Error)三类。可查异…...
ShardingSphere|shardingJDBC - 在使用数据分片功能情况下无法配置读写分离
问题场景: 最近在学习ShardingSphere,跟着教程一步步做shardingJDBC,但是想在开启数据分片的时候还能使用读写分离,一直失败,开始是一直能读写分离,但是分偏见规则感觉不生效,一直好像是走不进去…...
char s1[len + 1]; 报错说需要常量?
在C中,字符数组的大小必须是常量表达式,不能使用变量 len 作为数组大小。为了解决这个问题,你可以使用 new 运算符动态分配字符数组的内存,但在使用完后需要手动释放。 还有啥是只能这样的,还是说所有的动态都需要new&…...
【Linux】CentOS-6.8超详细安装教程
文章目录 1.CentOS介绍:2.必要准备:3.创建虚拟机:4 .安装系统 1.CentOS介绍: CentOS是一种基于开放源代码的Linux操作系统,它以其稳定性、安全性和可靠性而闻名,它有以下特点: 开源性࿱…...
【Java 进阶篇】MySQL启动与关闭、目录结构以及 SQL 相关概念
MySQL 服务启动与关闭 MySQL是一个常用的关系型数据库管理系统,通过启动和关闭MySQL服务,可以控制数据库的运行状态。本节将介绍如何在Windows和Linux系统上启动和关闭MySQL服务。 在Windows上启动和关闭MySQL服务 启动MySQL服务 在Windows上&#x…...
Android 11.0 mt6771新增分区功能实现一
1.前言 在11.0的系统开发中,在对某些特殊模块中关于数据的存储方面等需要新增分区来保存, 所以就需要在系统分区新增分区,接下来就来实现这个功能 2.mt6771新增分区功能实现一的核心类 build/make/core/Makefile build/make/core/board_config.mk build/make/core/config…...
LiveData简单使用
1.LiveData是基于观察者模式,可以用于处理消息的订阅分发的组件。 LiveData组件有以下特性: 1) 可以感知Activity、Fragment生命周期变化,因为他把自己注册成LifecycleObserver。 2) LiveData可以注册多个观察者,只有数据…...
手动实现Transformer
Transformer和BERT可谓是LLM的基础模型,彻底搞懂极其必要。Transformer最初设想是作为文本翻译模型使用的,而BERT模型构建使用了Transformer的部分组件,如果理解了Transformer,则能很轻松地理解BERT。 一.Transformer模型架构 1…...
leetcode456 132 Pattern
给定数组,找到 i < j < k i < j < k i<j<k,使得 n u m s [ i ] < n u m s [ k ] < n u m s [ j ] nums[i] < nums[k] < nums[j] nums[i]<nums[k]<nums[j] 最开始肯定想着三重循环,时间复杂度 O ( n 3 )…...
WordPress外贸建站Astra免费版教程指南(2023)
在WordPress的外贸建站主题中,有许多备受欢迎的主题,如AAvada、Astra、Hello、Kadence等最佳WordPress外贸主题,它们都能满足建站需求并在市场上广受认可。然而,今天我要介绍的是一个不断颠覆建站人员思维的黑马——Astra主题。 …...
Vue之ElementUI实现登陆及注册
目录 编辑 前言 一、ElementUI简介 1. 什么是ElementUI 2. 使用ElementUI的优势 3. ElementUI的应用场景 二、登陆注册前端界面开发 1. 修改端口号 2. 下载ElementUI所需的js依赖 2.1 添加Element-UI模块 2.2 导入Element-UI模块 2.3 测试Element-UI是否能用 3.编…...
网络代理的多面应用:保障隐私、增强安全和数据获取
随着互联网的发展,网络代理在网络安全、隐私保护和数据获取方面变得日益重要。本文将深入探讨网络代理的多面应用,特别关注代理如何保障隐私、增强安全性以及为数据获取提供支持。 1. 代理服务器的基本原理 代理服务器是一种位于客户端和目标服务器之间…...
字节一面:深拷贝浅拷贝的区别?如何实现一个深拷贝?
前言 最近博主在字节面试中遇到这样一个面试题,这个问题也是前端面试的高频问题,我们经常需要对后端返回的数据进行处理才能渲染到页面上,一般我们会讲数据进行拷贝,在副本对象里进行处理,以免玷污原始数据,…...
协议-TCP协议-基础概念02-TCP握手被拒绝-内核参数-指数退避原则-TCP窗口-TCP重传
协议-TCP协议-基础概念02-TCP握手被拒绝-TCP窗口 参考来源: 《极客专栏-网络排查案例课》 TCP连接都是TCP协议沟通的吗? 不是 如果服务端不想接受这次握手,它会怎么做呢? 内核参数中与TCP重试有关的参数(两个) -net.ipv4.tc…...
PDF文件压缩软件 PDF Squeezer mac中文版软件特点
PDF Squeezer mac是一款macOS平台上的PDF文件压缩软件,可以帮助用户快速地压缩PDF文件,从而减小文件大小,使其更容易共享、存储和传输。PDF Squeezer使用先进的压缩算法,可以在不影响文件质量的情况下减小文件大小。 PDF Squeezer…...
VS+Qt+opencascade三维绘图stp/step/igs/stl格式图形读取显示
程序示例精选 VSQtopencascade三维绘图stp/step/igs/stl格式图形读取显示 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《VSQtopencascade三维绘图stp/step/igs/stl格式图形读取显示》编写…...
如何在Ubuntu中切换root用户和普通用户
问题 大家在新装Ubuntu之后,有没有发现自己进入不了root用户,su root后输入密码根本进入不了,这怎么回事呢? 打开Ubuntu命令终端; 输入命令:su root; 回车提示输入密码; 提示&…...
从零开始之了解电机及其控制(10)空间矢量理论
与一维数字转子位置不同,电流和电压都是二维的。可以在矩形笛卡尔平面中考虑这些尺寸。 用旋转角度和幅度来描述向量 虽然电流命令的幅度和施加的电压是进入控制器的误差项的函数,它们施加的角度是 d-q 轴方向的函数,因此也是转子位置的函数。…...
PSINS工具箱学习(一)下载安装初始化、SINS-GPS组合导航仿真、习惯约定与常用变量符号、数据导入转换、绘图显示
原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 一、前言二、相关资源三、下载安装初始化1、下载PSINSyymmdd.rar工具箱文件2、解压文件3、初始化4、启动工具箱导览 四、习惯约定与常用变量符号1…...
国庆day1---消息队列实现进程之间通信方式代码,现象
snd: #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)typedef struct{ long msgtype; //消息类型char data[1024]; //消息正文 }Msg;#define SIZE sizeof(Msg)-sizeof(long)int main…...
大学生创业做网站的筹资方式/小学生简短小新闻
CAN FD描述 随着电动汽车,无人驾驶汽车技术的快速发展,以及对汽车高级驾驶辅助系统和人机交互的增加,传统的CAN总线在传输速率和带宽等方面越来越显得力不从心,因此改进版的CAN总线应运而生。从2012年第13届ICC大会上发布&#x…...
做网站是什么职业/阿里指数官网最新版本
创建一个新的用户: > $sudo useradd -m hadoop -s /bin/bash 设置用户的密码: > $sudo passwd hadoop 添加管理员权限: > $sudo adduser hadoop sudo 安装SSH,配置SSH无密码登陆: 安装SSH Server:…...
wordpress如何更改页脚背景颜色/百度灰色关键词代做
MariaDB数据库的创建语法,和MySQL数据库的语法是一样的 此文章是为了快速想起语法,不包含授权 MariaDB数据库创建用户 首先要知道一个事情,就是用户是 “用户名主机地址(网段)” 这样才算是一个用户 主机地址授权的范围大致如下: % – 表示:任意主机都可以连接到数据库(这很不…...
安徽建设教育协会网站/石家庄seo关键词排名
所有题目均有四种语言实现。C++ 实现目录、Python实现目录、Java实现目录、JavaScript实现目录 题目 对于任意两个正整数A和B,定义它们之间的差异值和相似值:差异值:A、B转换成二进制后,对于二进制的每一位,对应位置的bit值不相同则为1,否则为0;相似值:A、B转换成二进…...
怎么在ps里做网站设计/台州seo排名外包
TechEmpower第19轮编程语言框架性能排行榜2020年5月28日正式发布,详见官方博客:https://www.techempower.com/blog/2020/05/28/framework-benchmarks-round-19/,TechEmpower基准测试有许多场景(也称为测试类型),此次评测多了一个综合评分选项…...
上海电商网站开发/百度分析工具
原文:从头开始学JavaScript (二)——变量及其作用域一、变量 ECMAscript变量是松散型变量,所谓松散型变量,就是变量名称可以保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符。 定义:var firstDemo; 二、变量的作用域 2.…...