C++|哈希应用->布隆过滤器

目录

一、概念

二、模拟实现

三、布隆过滤器扩展应用


 

上一篇章学习了位图的使用,但它只适用于整数,对于要查询字符串是否在不在,位图并不能解决。所以针对这一问题,布隆过滤器可以派上用场,至于布隆过滤器是什么,其实并没有什么神奇的,就是在位图上套了哈希函数罢了,这两者组合起来就是布隆过滤器,而字符串就可以通过哈希函数转换成整数映射到位图当中去。 

一、概念

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

原理分析: 

我们来进行分析,为什么不存在是一定的,而存在是可能的,以及为什么要这样做。

首先来解释为什么要用多个哈希函数。

我们知道,字符串可以通过哈希函数转换成整数,但是哈希冲突是避免不了的,可能存在多个字符串通过哈希函数都得到了一样的整数,所以,为了尽量的减少哈希冲突,可以使用多个哈希函数,让字符串通过多个哈希函数得到多个映射位置,只要不是多个映射位置都相同,就不会冲突,这样大大提高了效率。至于要用几个哈希函数是适合的。

这里有一份研究:(转载详解布隆过滤器的原理,使用场景和注意事项 - 知乎 (zhihu.com))

其中误报率就是哈希冲突率 

其中k、m、n满足:

 其中k、m、p满足:

我们可以发现,哈希函数用的越多,哈希冲突率就越低,但是哈希函数到3之后,误报率已经很低了,其次,当哈希函数、插入元素固定,所开空间越大,误报率也越低。

用一张图来表示通过哈希函数映射到位图中:

那么综上,即使采用了多个哈希函数,也依然可能会存在哈希冲突,所以在判断东西在不在时,若返回的是存在,这有可能是误判,说明映射的位置依然可能完全相同,而不存在时,说明映射的位置不完全相同,这是正确的结果,为了确保冲突率,我们在模拟实现的时候就采用3个哈希函数。

二、模拟实现

#include "MyBitSet.h"//在上一篇章已实现
struct BKDRHash
{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){//BKDRhash *= 31;hash += e;}return hash;}
};struct APHash
{size_t operator()(const string& key){size_t hash = 0;for (size_t i = 0; i < key.size(); i++){if ((i & 1) == 0){hash ^= ((hash << 7) ^ key[i] ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ key[i] ^ (hash >> 5)));}}return hash;}
};
struct DJHash
{size_t operator()(const string& key){register size_t hash = 5381;for(auto e : key){hash += (hash << 5) + e;}return hash;}
};
namespace bit
{template<size_t N, class K = string, //默认输入的是字符串class HashFunc1 = BKDRHash,class HashFunc2 = APHash,class HashFunc3 = DJHash>class BloomFilter{public:void set(const K& key){//获取三个映射位置int hash1 = HashFunc1()(key) % N;int hash2 = HashFunc2()(key) % N;int hash3 = HashFunc3()(key) % N;_blf.set(hash1);_blf.set(hash2);_blf.set(hash3);}bool test(const K& key){//key不存在是准确的。int hash1 = HashFunc1()(key) % N;if (_blf.test(hash1) == false)return false;int hash2 = HashFunc2()(key) % N;if (_blf.test(hash2) == false)return false;int hash3 = HashFunc3()(key) % N;if (_blf.test(hash3) == false)return false;//key存在可能有误判return true;}private:bitset<N> _blf;};
}void TestBF1()
{bit::BloomFilter<100> bf;bf.set("猪八戒");bf.set("沙悟净");bf.set("孙悟空");bf.set("二郎神");cout << bf.test("猪八戒") << endl;cout << bf.test("沙悟净") << endl;cout << bf.test("孙悟空") << endl;cout << bf.test("二郎神") << endl;cout << bf.test("二郎神1") << endl;cout << bf.test("二郎神2") << endl;cout << bf.test("二郎神 ") << endl;cout << bf.test("太白晶星") << endl;
}void TestBF2()
{srand(time(0));const size_t N = 100000;bit::BloomFilter<N * 10> bf;std::vector<std::string> v1;//std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";std::string url = "猪八戒";for (size_t i = 0; i < N; ++i){v1.push_back(url + std::to_string(i));}for (auto& str : v1){bf.set(str);}// v2跟v1是相似字符串集(前缀一样),但是不一样std::vector<std::string> v2;for (size_t i = 0; i < N; ++i){std::string urlstr = url;urlstr += std::to_string(9999999 + i);v2.push_back(urlstr);}size_t n2 = 0;for (auto& str : v2){if (bf.test(str)) // 误判{++n2;}}cout << "相似字符串误判率:" << (double)n2 / (double)N << endl;// 不相似字符串集std::vector<std::string> v3;for (size_t i = 0; i < N; ++i){//string url = "zhihu.com";string url = "孙悟空";url += std::to_string(i + rand());v3.push_back(url);}size_t n3 = 0;for (auto& str : v3){if (bf.test(str)){++n3;}}cout << "不相似字符串误判率:" << (double)n3 / (double)N << endl;
}

测试:

#include <string>
#include "MyBloomFilter.h"int main()
{TestBF2();return 0;
}

 输出结果:

三、布隆过滤器扩展应用

1.给两个文件,分别由100亿个字符串,只有1G内存,如何找到两个文件交集?

假设每个字符串占50个字节,那么100亿就是5000字节,约等于500G,内存肯定存不下,此时可以采用哈希切分。如图:

 

2.给一个超过100G大小的log file,log中存着IP地址,设计算法找到出现次数最多的IP地址?

与第一题类似,先进行哈希切分,然后通过map统计每个小文件中IP地址出现的次数进行比较即可。 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java支付宝沙箱支付环境配置及简单测试

Java支付宝沙箱环境配置(测试) 1. 沙箱配置环境 沙箱应用 - 开放平台 (alipay.com) 2. 需要用到的基本信息 3. Pom文件添加依赖 <!--支付宝依赖 --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId…

周鸿祎:大模型不是风口和泡沫,将引领新工业革命

7月2日&#xff0c;2023全球数字经济大会人工智能高峰论坛举行。360集团创始人周鸿祎在论坛发表《构建“安全可信可控易用”的企业级AI大模型》主题演讲。他表示&#xff0c;大模型不是风口和泡沫&#xff0c;将引领新工业革命。在城市、行业、企业数字化转型到智能化的过程中&…

#### golang中【堆】的使用及底层 ####

声明&#xff0c;本文部分内容摘自&#xff1a; Go: 深入理解堆实现及应用-腾讯云开发者社区-腾讯云 数组实现堆 | WXue 堆&#xff08;Heap&#xff09;是实现优先队列的数据结构&#xff0c;Go提供了接口和方法来操作堆。 应用 package mainimport ("container/heap&q…

C++:类型转换

目录 一、C语言中的类型转换 二、为什么C要新的转换格式 三、 C强制类型转换 1.static_cast 2.reinterpret_cast 3.const_cast 4.dynamic_cast 一、C语言中的类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&…

Land survey boundary report (template)

Land survey boundary report (template) 土地勘测定界报告&#xff08;模板&#xff09;.doc

可视化学习之pytorch可视化工具visdom

文章摘自详解PyTorch可视化工具visdom&#xff08;一&#xff09;-CSDN博客 模型训练过程中需要实时监听并可视化一些数据&#xff0c;如损失值loss&#xff0c;正确率acc等。在tensorflow中&#xff0c;使用的工具为tensorboard&#xff1b; 安装一下试试 1.安装 pip inst…

Android的课程学习助手APP-计算机毕业设计源码19307

基于Android的课程学习助手APP 摘 要 在数字化、信息化的时代背景下&#xff0c;移动学习已成为现代教育发展的重要趋势。为了满足广大学生对高效、便捷学习方式的迫切需求&#xff0c;一款基于Android平台的课程学习助手APP应运而生。这款APP巧妙地将先进的信息技术与学习体验…

通过一个单相逆变器仿真深度学习PR控制器

目录 前言 ​编辑 PR控制器的理论 PR控制器不同表达式及其建模 PR控制器连续积分组合及模型 PR控制器连续传递函数及模型 PR控制器离散积分及模型 PR控制器离散传递函数及模型 PR控制器差分方程及模型 系统仿真效果 总结 前言 在项目开发中常用PI控制器&#xff0c;这次在…

解读 Amazon Q | 用 AI 聊天机器人连接你与未来的无限可能

在美国当地时间11月28日&#xff0c;亚马逊云科技在拉斯维加斯举办了 re:Invent 大会&#xff0c;大会介绍了许多今年来新增的核心产品与功能&#xff0c;着重讲解了生成式 AI 引领人工智能未来的前进方向&#xff0c;亚马逊作为云计算领域的龙头&#xff0c;相信会继续给我们的…

基于路径长度的样条插补算法(自动驾驶和路径跟踪控制适用)

以前在做车辆跟踪控制的时候发现在针对有多个X和多个Y对应的路径插补时候&#xff0c;总是报错&#xff0c;因为MATLAB里面的interp1插补函数它要求x要唯一对应一个y&#xff0c;当路径以单独的x或者y来求插补时候的时候就报错。由于在使用Matlab的interp1函数进行插值时&#…

重生之算法刷题之路之链表初探(三)

算法刷题之路之链表初探&#xff08;三&#xff09; 今天来学习的算法题是leecode2链表相加&#xff0c;是一道简单的入门题&#xff0c;但是原子在做的时候其实是有些抓耳挠腮&#xff0c;看了官解之后才恍然大悟&#xff01; 条件 项目解释 有题目可以知道&#xff0c;我们需…

C#Modbus专题

1&#xff0c;辅助工具。 1&#xff0c;虚拟串口工具&#xff08;vspd.exe&#xff09; 2&#xff0c;Modubus模拟主站(Modbus Poll) 3&#xff0c;Modbus模拟从站(Modbus Slave) 4&#xff0c;OPC服务软件(KEPServerEx V4.0)。 下载链接&#xff1a;https://download.csdn.n…

Redisson框架

1. Redisson锁与Redis订阅与发布模式的联系&#xff1a; Redisson锁中&#xff0c;使用订阅发布模式去通知等待锁的客户端&#xff1a;锁已经释放&#xff0c;可以进行抢锁。 publish channel_name message&#xff1a;将消息发送到指定频道 解锁时&#xff0c;在Lua解锁脚本…

算法思想总结:优先级队列

一、最后一块石头的重量 . - 力扣&#xff08;LeetCode&#xff09; 我们每次都要快速找到前两个最大的石头进行抵消&#xff0c;这个时候用优先级队列&#xff08;建大堆&#xff09;,不断取堆顶元素是最好的&#xff01;每次删除堆顶元素后&#xff0c;可以自动调整&#xf…

[C++][CMake][CMake基础]详细讲解

目录 1.CMake简介2.大小写&#xff1f;3.注释1.注释行2.注释块 4.日志 1.CMake简介 CMake是一个项目构建工具&#xff0c;并且是跨平台的 问题 – 解决 如果自己动手写Makefile&#xff0c;会发现&#xff0c;Makefile通常依赖于当前的编译平台&#xff0c;而且编写Makefile的…

【动态规划】动态规划一

动态规划一 1.第 N 个泰波那契数2.面试题 08.01. 三步问题3.使用最小花费爬楼梯4.解码方法 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.…

分布式限流:Spring Cloud Gateway 限流

分布式限流&#xff1a;Spring Cloud Gateway 限流 在现代微服务架构中&#xff0c;流量控制是一个至关重要的部分。分布式限流作为一种有效的流量控制手段&#xff0c;能够帮助我们保护系统不被突发的流量冲垮。Spring Cloud Gateway支持多种限流方式。 什么是分布式限流 分…

模拟5亿年自然进化史,全新蛋白质大模型ESM3诞生!前Meta老将力作LeCun转赞

模拟5亿年自然进化史&#xff0c;全新蛋白质大模型ESM3诞生&#xff01;前Meta老将力作LeCun转赞。 能抗衡AlphaFold 3的生命科学大模型终于出现了。初创公司Evolutionary Scale AI发布了他们最新的98B参数蛋白质语言模型ESM3。不仅支持序列、结构、功能的all-to-all推理&#…

Unreal Engine@Jetson Orin Nano尚不支持

Unreal EngineJetson Orin Nano尚不支持 1. 源由2. Unreal Engine介绍3. 问题4. 编译方法5. 补充6. 其他 1. 源由 最近在看SC-Explorer方面的内容&#xff0c;在模拟方面采用了Unreal Engine。 本打算跑下模拟&#xff0c;因此打算在JetsonOrin的板子上试试看。 2. Unreal En…

opencv实现目标检测功能----20240704

早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。这次我们使用Opencv深度学习的功能实现目标检测的功能,模型选用MobileNetSSD_deploy.caffemodel。 模型加载…