C++中布隆过滤器

ops/2024/10/18 14:24:36/

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

布隆过滤器

布隆过滤器的原理

添加元素

具体使用场景

BKDRHash

APHash

DJBHash

哈希分割


布隆过滤器

布隆过滤器(Bloom Filter)是一种数据结构,用于快速检查一个元素是否属于一个集合中。它通过使用一系列哈希函数和位数组来实现。当一个元素被添加到布隆过滤器时,将对其进行多次哈希,并将相应的位数组位置设置为1。当检查一个元素是否在集合中时,布隆过滤器会对该元素进行相同的哈希,并检查对应的位数组位置是否都为1,若其中有一个位置不为1,则可以确定该元素不在集合中;若都为1,则该元素可能在集合中(存在一定的误判率)。

布隆过滤器的主要优点是空间效率和查询速度高,因为它不需要存储实际的元素内容,只需要存储一系列位的数组。但是,布隆过滤器也有一定的缺点,主要是存在误判率(可能会判断一个不在集合中的元素为在集合中)以及不支持元素的删除操作。

常见的应用场景包括网络爬虫中的URL去重、数据库查询优化中的缓存、拼写检查等。

布隆过滤器的原理

一个值映射多个比特位,还是可能存在冲突,映射多个位,降低误判的概率,布隆过滤器的数据结构是一个位向量,也就是一个由0、1所组成的bit数组

添加元素

每个元素添加进布隆过滤器前,都会经过多个不同的哈希函数,计算出不同的哈希值,然后映射到位向量上,也就是对应的位"置1"

对元素进行多个不同的哈希运算,得到多个位下标,判断所有映射位置是否都为1,若是,则元素可能存在,否则一定不存在

注意:由于不同的值通过哈希函数之后可能会映射到相同的位置,因此如果一个不存在的元素对应的位都被其他元素所设置1,则查询时就会误判

具体使用场景

如果存在一个数据库,存储的都是都是用的昵称,我们用注册时,需要注册昵称,但是昵称不能和数据库存储的昵称重复,所以就需要在用户注册昵称时,去查询数据库是否存在该昵称。但是传统查询效率太低了,使用哈希表的方式查询的话,可以将字符串转为整形,进行映射但是会面临一个问题,整形开辟的最大空间是42亿多(因为最大的无符号整数是2^32或2^64),但是字符串接近无限大,例如,一个10长度的单词,就有19275223968000之多所以用整数完全存储不了字符串,而且单纯的哈希表,可能导致多个字符串对应一个整数。因此布隆过滤器非常有必要,布隆过滤器底层思想还是哈希,和传统的哈希表不一样。布隆过滤器使用了位图,用多个位置表示一个字符串,这里我们需要将字符串转成的方法。

BKDRHash
unsigned int BKDRHash(const std::string& key) {unsigned int seed = 131; // 31 131 1313 13131 131313 etc..unsigned int hash = 0;for (char c : key) {hash = hash * seed + c;}return hash;
}

稳定性:较为稳定,具有良好的分布性。

APHash
unsigned int APHash(const std::string& key) {unsigned int hash = 0;for (char c : key) {hash ^= ((hash << 7) ^ c ^ (hash >> 3));}return hash;
}

稳定性:稳定,适用于大多数情况。

DJBHash
unsigned int DJBHash(const std::string& key) {unsigned int hash = 5381;for (char c : key) {hash = ((hash << 5) + hash) + c;}return hash;
}

稳定性:非常稳定,被广泛使用。

一般使用三个转换方法效率就很高了(就是用三个比特位对应一个字符串)。使用布隆过滤器,我们就可以准觉的判断一个昵称是否在数据库已经存在,这样的时间效率O(1)

但是,布隆过滤器也有一定的缺点,主要是存在误判率(可能会判断一个不在集合中的元素为在集合中)以及不支持元素的删除操作。

哈希分割

1. 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法近似算法

2. 如何扩展BloomFilter使得它支持删除元素的操作

假设平均一个query(查询字符)50byte

1G约等于10byte

100亿query 5000byte 约等于500G

哈希表/红黑树空间严重不足

1.

第一步:将两个文件分别哈希分割到多个小文件中

读取每个query,计算i=Hash(query)%500,i是几,query就进入到Ai小文件

读取每个query,计算i=Hash(query)%500,i是几,query就进入到Bi小文件

2.Ai和Bi分别插入到setA和setB,快速找交集

有一个问题,就是分割文件也挺大怎么办,例如:10G文件

情况有两种:

1)这个文件中有很多重复query

2))这个文件中有不同的query

解决方案:

其实很简单,Ai和Bi分别直接插入到setA和setB,如果是情况1),query大量重复,后面插入会失败(因为set不允许重复值插入),情况二,不断插入set以后,内存不足就会抛出异常,就需要换一个哈希函数,进行二次切分,再找交集

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,

如何找到top K的IP?

1.i=Hash(ip)%100

这个ip就进入同一个文件,相同的ip一定会进同一个文件,不同的ip也会进同一个文件,但是同一个ip不会进不同的文件

2.用map依次统计每个文件ip次数,然后比较每个文件最多的ip

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 


http://www.ppmy.cn/ops/21118.html

相关文章

Pandas 2.2 中文官方教程和指南(十七)

原文&#xff1a;pandas.pydata.org/docs/ 重复标签 原文&#xff1a;pandas.pydata.org/docs/user_guide/duplicates.html Index对象不需要是唯一的&#xff1b;你可以有重复的行或列标签。这一点可能一开始会有点困惑。如果你熟悉 SQL&#xff0c;你会知道行标签类似于表上的…

pikachu-xss

反射型xss&#xff08;get&#xff09; 1.字数限制 按原本的做法&#xff0c;应该先写一个script标签测试一下&#xff0c;但是发现有字符限制。 2.解决方法 这里有两个可以插入的地方&#xff0c;一个是submit的提交框&#xff0c;另一个是url地址栏 submit&#xff1a;修…

GEE案例——1990-2023年计算某个区域的NDVI时序变化轨迹(以徐州市为例)

简介 我们在长时间序列的分析中,往往会根据影像时序的长短来进行分析,这里我们以NDVI指数进行长时序分析,来实现NDVI1990-2023年长时序的监测。 时序监测 时序监测是指通过对连续时间序列的遥感图像进行分析,以观察和监测地表特征、植被生长、环境变化等的动态变化过程。…

Ubuntu设置jar包开机自启(亲测有效)

1、在/etc/init.d/下新建一个脚本 cmis-admin.sh 2、在脚本中进行编辑 #!/bin/sh ### BEGIN INIT INFO # Provides: cmis-admin.sh # Required-start: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog # Defa…

堆的介绍,实现(c语言实现)

目录 堆的概念 堆的性质&#xff1a; 堆的分类 父子结点的下标关系 堆的向下调整算法 ​编辑小堆 大堆 建堆 堆的向上调整算法 小堆 大堆 堆的基本操作 定义堆 初始化堆 销毁堆 打印堆 堆的插入 堆的删除 大堆&#xff08;Max Heap&#xff09;的向下调整算法…

javaEE初阶——多线程(九)——JUC常见的类以及线程安全的集合类

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程专题的最后一篇文章:关于JUC常见的类以及线程安全的集合类 如果有不足的或者错误的请您指出! 目录 3.JUC(java.util.concurrent)常见的类3.1Callable接口3.2 RentrantLoc…

SpringBoot + Dubbo + zookeeper实现

目录 一&#xff0c;框架搭建 1. 启动zookeeper &#xff01; 2. IDEA创建一个空项目&#xff1b; 3.创建一个模块&#xff0c;实现服务提供者&#xff1a;provider-server &#xff0c; 选择web依赖即可 4.项目创建完毕&#xff0c;我们写一个服务&#xff0c;比如卖票的服…

MySQL数据库总结

作者&#xff1a;爱塔居-CSDN博客 专栏&#xff1a;数据库 目录 前言 一、数据库操作 1.1 创建数据库 1.2 显示当前数据库 1.3 使用数据库 1.4 删除数据库 二、表的操作 2.1 查看表结构 2.2 创建表 2.3 删除表 三、表的增删改查操作&#xff08;CRUD) 3.1 新增 3.…