新C++(13):布隆过滤器

news2024/11/15 11:54:29

"明白成功,不一定赢在起跑线!"


位图反思

上篇呢,我们在遇到海量数据时,如果只是进行诸如,查找一个数在不在这样的简单逻辑情况,在使用数组这样的内存容器,无法存储这么多数据时,我们采用新的数据结构——"位图"。

那么位图有什么弊端嘛?

我们举一个例子,要在1,2,3,4,2^32-1,2^32-2,2^32-3中查看5在不在!是的数据很大,所以我们开位图结构要开足足2^32-1个比特位,用于直接定址映射。但是,你会发现,你就仅仅是在这不到10个数中,查找5,却开开辟了512MB空间用来标记。

因此,位图只适合以用于 "数据量范围集中" , 并且是整数! 你的位图结构不可能存储string类型的对象。

那如果此时给你一个全部用户的名单,你要在用户名单中找出进入黑名单的用户,并将它剔除,你如何快速找到该名字并判断?? 位图结构肯定不行! 因为姓名 不是整数。

----前言


一、布隆过滤器简介

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的 优点是空间效率和查询时间都比一般的算法要好的多,缺点是 有一定的误识别率和删除困难。 取自这里

看文字不好理解,我们直接上图。

"在"是准确,还是"不在"是准确?

字符串转换不像整数!整数就是一个一个的Key值。但是字符串转换后的整型,是有可能一样的!这和哈希冲突类似。

因此,布隆过滤器是存在误判的

为了降低误判率!我们时常会多增添几个哈希函数,让一个字串映射多个位置。相应地,你较之前降低了误判的概率,但却让一个值映射多个位置,无疑增加了空间的消耗。当然,作何取舍是需要我们去权衡的。

布隆过滤器的价值在于:
"不在",是准确的!"在",是不准确(存在误判)。

二、布隆过滤器实现

(1)布隆过滤器长度

布隆过滤器的底层,其实就是位图结构。当然,与位图结构有去别的是,你不知道开辟多少个bit位。你使用一个哈希函数,那么表示一个数值在不在的就是1bit,如果你用两个哈希函数,那么表示一个数值在不在的就是2bit,如果你用三个哈希函数……这里有一个公式,可以计算出布隆过滤器开辟的空间大小 取自这里

(2)哈希函数选择

字符串转整数的函数特别多,这里就截取几个。 取自这里

    //N表示 最多存储的个数
    template<size_t N,
    size_t X = 6,
    class K = std::string,
    class HashFunc1 = BKDRHash,
    class HashFunc2 = APHash,
    class HashFunc3 = DJBHash>
    class bloomfilter
    {
    public:
        void set(const K& key)
        {
            //计算 下标
            size_t hash1 = HashFunc1()(key) % (N * X);
            size_t hash2 = HashFunc2()(key) % (N * X);
            size_t hash3 = HashFunc3()(key) % (N * X);

            //设置进位图
            _bloomfilter.set(hash1);
            _bloomfilter.set(hash2);
            _bloomfilter.set(hash3);
        }

        bool test(const K& key)
        {
            size_t hash1 = HashFunc1()(key) % (N * X);
            //只有不在才是准确的
            if (!_bloomfilter.test(hash1))
            {
                return false;
            }
        
            size_t hash2 = HashFunc2()(key) % (N * X);
            if (!_bloomfilter.test(hash2))
            {
                return false;
            }

            size_t hash3 = HashFunc3()(key) % (N * X);
            if (!_bloomfilter.test(hash3))
            {
                return false;
            }

            //说明该字符串各个位置 都映射了
            //虽然 返回true  但可能存在误判
            return true;
        }

    private:
        std::bitset<N* X> _bloomfilter;
    };

(3)set\test

void set(const K& key)
        {
            //计算 下标
            size_t hash1 = HashFunc1()(key) % (N * X);
            size_t hash2 = HashFunc2()(key) % (N * X);
            size_t hash3 = HashFunc3()(key) % (N * X);

            //设置进位图
            _bloomfilter.set(hash1);
            _bloomfilter.set(hash2);
            _bloomfilter.set(hash3);
        }

        bool test(const K& key)
        {
            size_t hash1 = HashFunc1()(key) % (N * X);
            //只有不在才是准确的
            if (!_bloomfilter.test(hash1))
            {
                return false;
            }
        
            size_t hash2 = HashFunc2()(key) % (N * X);
            if (!_bloomfilter.test(hash2))
            {
                return false;
            }

            size_t hash3 = HashFunc3()(key) % (N * X);
            if (!_bloomfilter.test(hash3))
            {
                return false;
            }

            //说明该字符串各个位置 都映射了
            //虽然 返回true  但可能存在误判
            return true;
        }

不解释。

(4)测试

分别产含有10000个字符串集的数组,其中的元素有相似的和非相似的。

    void TestBloomFilter()
    {
        srand(time(0));
        const size_t N = 10000;
        bloomfilter<N> bf;

        //1.相似字符集
        std::vector<std::string> Array_Same;
        std::string url = "www.baidu.com";
        for (size_t i = 0; i < N; ++i)
        {
            Array_Same.push_back(url + std::to_string(i));
        }

        //设置
        for (auto& e : Array_Same)
        {
            bf.set(e);
        }

        std::vector<std::string> Array_Differ;
        for (size_t i = 0;i < N;++i)
        {
            Array_Differ.push_back(url + std::to_string(rand() + i));
        }

        //查找
        size_t n2 = 0;
        for (auto& str : Array_Differ)
        {
            if (bf.test(str))
            {
                ++n2;
            }
        }
        //第二个字符集 映射出来的位置 与 第一字串集 比较
        std::cout << "相似字符 串误判率:" << (double)n2 / (double)N << std::endl;
    
        std::vector<std::string> Array;
        for (size_t i = 0; i < N; ++i)
        {
            std::string url = "qq.com";
            url += std::to_string(i + rand());
            Array.push_back(url);
        }

        n2 = 0;
        for (auto& e : Array)
        {
            if (bf.test(e))
            {
                n2++;
            }
        }
        std::cout << "不相似字符 串误判率:" << (double)n2 / (double)N << std::endl;
    }

也进一步证明了,布隆过滤器的误差判断。

总结:

布隆过滤器最重要的是它是存在是准确的,还是不存在是准确的,这是面试经常问的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络第八版——第三章课后题答案(超详细)

第三章 该答案为博主在网络上整理&#xff0c;排版不易&#xff0c;希望大家多多点赞支持。后续将会持续更新&#xff08;可以给博主点个关注~ 第一章 答案 第二章 答案 【3-01】数据链路&#xff08;即逻辑链路&#xff09;与链路&#xff08;即物理链路&#xff09;有何区…

Numpy/Pandas常用函数

&#x1f442; 不露声色 - Jam - 单曲 - 网易云音乐 目录 &#x1f33c;前言 &#x1f44a;一&#xff0c;Python列表函数 &#x1f44a;二&#xff0c;Numpy常用函数 1&#xff0c;生成数组 2&#xff0c;描述数组属性 3&#xff0c;常用统计函数 4&#xff0c;矩阵运…

Soul 云原生网关最佳实践

作者&#xff1a;Soul 运维 公司介绍 Soul 是基于兴趣图谱和游戏化玩法的产品设计&#xff0c;属于新一代年轻人的虚拟社交网络。成立于2016年&#xff0c;Soul 致力于打造一个“年轻人的社交元宇宙”&#xff0c;最终愿景是“让天下没有孤独的人”。在 Soul&#xff0c;用户…

springboot复习(黑马)(持续更新)

学习目标基于SpringBoot框架的程序开发步骤熟练使用SpringBoot配置信息修改服务器配置基于SpringBoot的完成SSM整合项目开发一、SpringBoot简介1. 入门案例问题导入SpringMVC的HelloWord程序大家还记得吗&#xff1f;SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计…

为什么低代码最近又火了起来?是钉钉的原因吗?

为什么低代码最近又火了起来&#xff1f;是钉钉的原因吗&#xff1f; 钉钉的入局固然推动了人们对于低代码的讨论&#xff0c;但低代码由来已久&#xff0c;其火爆其实是大势所趋。 那么本篇文章将来解读一下&#xff1a;为什么低代码最近又火了&#xff1f;是资本的推动还是…

佩戴舒适的蓝牙耳机有哪些?佩戴舒适的蓝牙耳机推荐

音乐对许多人而言&#xff0c;都是一种抚慰生命的力量&#xff0c;特别是在上下班的时候&#xff0c;在熙熙攘攘的人流中&#xff0c;戴着耳机听一首动听的曲子&#xff0c;无疑会让人心情变得更加舒畅&#xff0c;要想获得出色的音乐体验&#xff0c;没有一副出色的耳机可不行…

动态内存基础(三)

动态内存的相关问题 ● sizeof 不会返回动态分配的内存大小 #include<iostream> #include<new> #include<memory> #include<vector> int main(int argc, char *argv[]) {int* ptr new int(3);std::cout << sizeof(ptr) << std::endl; //…

阶段式/瀑布完整软件研发流程

软件产品开发流程&#xff1a;下图所示的是一个软件产品开发大体上所需要经历的全部流程&#xff1a;编辑1、启动在项目启动阶段&#xff0c;主要确定项目的目标及其可行性。我们需要对项目的背景、干系人、解决的问题等等进行了解。并编制项目章程和组建项目团队&#xff0c;包…

STM32实战项目-状态机函数应用

前言&#xff1a; 本章主要介绍一下&#xff0c;状态机在工程中的应用&#xff0c;下面我会通过这种方式点亮LED灯&#xff0c;来演示他的妙用。 目录 1、状态机应用 1.1流水灯函数 1.1.1led.h 1.1.2led.c 1.2状态机函数 1.2.1定义举常量 1.2.2结构体封装 1、状态机应…

设计模式-01

1&#xff0c;设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大&#xff08;Christopher Alexand…

VUE3使用JSON编辑器

1、先看看效果图&#xff0c;可以自行选择展示效果 2、这是我在vue3项目中使用的JSON编辑器&#xff0c;首先引入第三方插件 npm install json-editor-vue3yarn add json-editor-vue33、引入到项目中 // 导入模块 import JsonEditorVue from json-editor-vue3// 注册组件 …

【pytorch onnx】Pytorch导出ONNX及模型可视化教程

文章目录1 背景介绍2 实验环境3 torch.onnx.export函数简介4 单输入网络导出ONNX模型代码实操5 多输入网络导出ONNX模型代码实操6 ONNX模型可视化7 ir_version和opset_version修改8 致谢原文来自于地平线开发者社区&#xff0c;未来会持续发布深度学习、板端部署的相关优质文章…

RocketMQ5.1控制台的安装与启动

RocketMQ控制台的安装与启动下载修改配置开放端口号重启防火墙添加依赖编译 rocketmq-dashboard运行 rocketmq-dashboard本地访问rocketmq无法发送消息失败问题。connect to &#xff1c;公网ip:10911&#xff1e; failed下载 下载地址 修改配置 修改其src/main/resources中…

【操作系统原理实验】银行家算法模拟实现

选择一种高级语言如C/C等&#xff0c;编写一个银行家算法的模拟实现程序。1) 设计相关数据结构&#xff1b;2) 实现系统资源状态查看、资源请求的输入等模块&#xff1b;3) 实现资源的预分配及确认或回滚程序&#xff1b;4) 实现系统状态安全检查程序&#xff1b;5) 组装各模块…

TCP模拟HTTP请求

HTTP的特性HTTP是构建于TCP/IP协议之上&#xff0c;是应用层协议&#xff0c;默认端口号80HTTP协议是无连接无状态的HTTP报文请求报文HTTP协议是以ASCⅡ码传输&#xff0c;建立在TCP/IP协议之上的应用层规范。HTTP请求报文由请求行&#xff08;request line&#xff09;、请求头…

Flutter 自定义今日头条版本的组件,及底部按钮切换静态样式

这里写目录标题1. 左右滑动实现标题切换&#xff0c;点击标题也可实现切换&#xff1b;2. 自定义KeepAliveWrapper 缓存页面&#xff1b;2.2 使用3. 底部导航切换&#xff1b;4. 自定义中间大导航&#xff1b;5.AppBar自定义顶部按钮图标、颜色6. Tabbar TabBarView实现类似头条…

iOS开发之UIStackView基本运用

UIStackView UIStackView是基于自动布局AutoLayout&#xff0c;创建可以动态适应设备方向、屏幕尺寸和可用空间的任何变化的用户界面。UIStackView管理其ArrangedSubview属性中所有视图的布局。这些视图根据它们在数组中的顺序沿堆栈视图的轴排列。由axis, distribution, align…

java医院云HIS系统:融合B/S版电子病历系统 能与公卫、PACS等各类外部系统融合

医院HIS系统源码 云HIS系统源码&#xff1a;SaaS运维平台完整文档 有源码&#xff0c;有演示 java基层医院云his系统 融合B/S版电子病历系统&#xff0c;支持电子病历4级 拥有自主知识产权。 看演示及源码可私信我哦&#xff01; 一、系统概述 一款满足二甲医院、基层医疗机构…

九、会话技术CookieSession

会话技术 1&#xff0c;会话跟踪技术的概述 对于会话跟踪这四个词&#xff0c;我们需要拆开来进行解释&#xff0c;首先要理解什么是会话&#xff0c;然后再去理解什么是会话跟踪: 会话:用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有…

3D目标检测(二)—— 直接处理点云的3D目标检测网络VoteNet、H3DNet

前言上次介绍了基于Point-Based方法处理点云的模块&#xff0c;3D目标检测&#xff08;一&#xff09;—— 基于Point-Based方法的PointNet点云处理系列,其中相关的模块则是构成本次要介绍的&#xff0c;直接在点云的基础上进行3D目标检测网络的基础。VoteNet对于直接在点云上预…