C++_布隆过滤器

       

目录

1、布隆过滤器的用法

2、布隆过滤器的查找 

3、布隆过滤器的删除

4、布隆过滤器的实现 

结语 


前言:

        布隆过滤器是一种概率型数据结构,采用的是哈希思想,他在位图的原有基础上做了升级,因为位图处理不了数据为字符串的情况,而布隆过滤器可以。布隆过滤器的作用是能够快速的判断某个数据存在与否,他也是通过哈希函数找到映射在位图上的位置,但是位图只映射一个位置,而布隆过滤器能够映射多个位置,这也是布隆过滤器和位图的区别所在。

1、布隆过滤器的用法

         哈希表能够处理多种类型的数据,但是哈希表所占空间过大,因此推出位图概念,但是位图所处理的数据过于单一,因此又推出布隆过滤器的概念,虽然布隆过滤器也是在bit位上进行操作的,但是布隆过滤器记录一个数据时用了多个哈希函数映射,因此布隆过滤器发生冲突的概率比较小。

        布隆过滤器具体示意图如下:

2、布隆过滤器的查找 

         布隆过滤器是通过多个哈希函数进行映射位置的,并且每个数据映射到的位置都会被置为1,那么查找一个数据时会出现两种情况:

        1、只要查找的数据对应的映射位置里有一个bit位是0,说明该数据不存在。

        2、若查找的数据对应的映射位置里都是1,那么该数据可能存在也可能不会存在,但是编译器会返回一个存在的结果给到用户(误判)。

        误判的示意图如下:

3、布隆过滤器的删除

        布隆过滤器是不支持删除操作的,因为从上文的叙述中可以得出,若有两个数据的bit位重复了,如果把一个数据删除,那么该数据的bit位肯定要置为0,但是该bit位的变动影响了其他数据。

        具体示意图如下:

4、布隆过滤器的实现 

        实现代码如下: 

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
#include<string>
#include<vector>
using namespace std;template<size_t N>
class bitset//位图
{
public:bitset(){_bits.resize(N / 8 + 1, 0);//位图的大小和初始化}void set(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] |= (1 << j);//或-只要有一个为1结果就为1}void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] &= ~(1 << j);//或-只要有一个为0结果就为0}bool find(size_t x){size_t i = x / 8;size_t j = x % 8;return _bits[i] & (1 << j);//_bits[i]为1说明该数据存在}private:vector<char> _bits;//位图其实是一个char类型的vector
};struct BKDRHash//哈希算法1
{size_t operator()(const string& s){size_t hash = 0;for (auto ch : s){hash += ch;hash *= 31;}return hash;}
};struct APHash//哈希算法2
{size_t operator()(const string& s){size_t hash = 0;for (size_t i = 0; i < s.size(); i++){size_t ch = s[i];if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash;}
};struct DJBHash//哈希算法3
{size_t operator()(const string& s){size_t hash = 5381;for (auto ch : s){hash += (hash << 5) + ch;}return hash;}
};// N最多会插入key数据的个数
template<size_t N,class K = string,class Hash1 = BKDRHash,class Hash2 = APHash,class Hash3 = DJBHash>class BloomFilter
{
public:void set(const K& key){size_t len = N * _X;//得到三个映射位置size_t hash1 = Hash1()(key) % len; _bs.set(hash1);size_t hash2 = Hash2()(key) % len;_bs.set(hash2);size_t hash3 = Hash3()(key) % len;_bs.set(hash3);}bool find(const K& key){size_t len = N * _X;//检查三个位置是否都为1size_t hash1 = Hash1()(key) % len;if (!_bs.find(hash1)){return false;}size_t hash2 = Hash2()(key) % len;if (!_bs.find(hash2)){return false;}size_t hash3 = Hash3()(key) % len;if (!_bs.find(hash3)){return false;}return true;}
private:static const size_t _X = 4;//_X越大,则开的bit位越多,越不容易出现误判bitset<N* _X> _bs;//期望位图开N* _X个bit位
};int main()
{BloomFilter<100> bs;//映射数据bs.set("sort");bs.set("bloom");bs.set("hello world!!");bs.set("qwer");//查找数据cout << bs.find("sort") << endl;cout << bs.find("bloom") << endl;cout << bs.find("hello world!!") << endl;cout << bs.find("qwer") << endl;cout << bs.find("abcd") << endl;return 0;
}

        运行结果:

结语 

        以上就是关于布隆过滤器的讲解,布隆过滤器本质上还是运用了位图的基础,只不过在此基础上进行了升级,布隆过滤器的优势在于可以使用相对较小的空间去判断大量的数据存在与否,这是其他数据结构所做不到的,当然布隆过滤器要承受一部分误判的风险。

        最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞👍+关注😎+收藏👌!如果有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!! 

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

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

相关文章

安全增强型 Linux

书接上篇 一查看selinux状态 SELinux的状态&#xff1a; enforcing&#xff1a;强制&#xff0c;每个受限的进程都必然受限 permissive&#xff1a;允许&#xff0c;每个受限的进程违规操作不会被禁止&#xff0c;但会被记录于审计日志 disabled&#xff1a;禁用 相关命令…

springboot集成logback打印彩色日志

一、logback介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站&#xff1a; logback.qos.ch。它当前分为以下三个模块&#xff1a; logback-core&#xff1a;其它两个模块的基础模块。logback-classic&#xff1a;它是log4j的一个改良版本&#xff0c;同时它完整实…

【国家机构关系】

国家机构 ■ 国家机构■ 国家主席■ 中央军事委员会■ 权力机关■ 司法机关■ 人民政府■ 人民法院■ 人民检察院 ■ 监察机关■ 最高人民检察院■ 地方各级人民检察院■ 军事检察院 ■ 行政机关■ 中央行政机■ 地方行政机关■ 城市管理局&#xff08;城管&#xff09; ■ 民族…

板级PDN(电源分配网络)设计要点综述

目录 目标阻抗去耦方法 确定目标阻抗 确定目标频点 VRM 去耦电容 安装电感 平面电容 总结 去耦电容 PCB叠层设计 扩展阅读 目标阻抗去耦方法 确定PCB去耦方案的策略是使用频域目标阻抗法&#xff0c;通过层间电容和分立电容器组合的使用&#xff0c;保证电源轨阻抗在…

TypeScript学习笔记(上):TypeScript的介绍、安装及常用类型

我对TypeScript的理解就是&#xff0c;TypeScript是增加了类型校验的JavaScript&#xff0c;能够把运行期错误提升至编译期 TypeScript是什么&#xff1f; TypeScript&#xff08;简称&#xff1a;TS&#xff09;是 JavaScript 的超集&#xff08;JS 有的 TS 都有&#xff09…

【LeetCode】升级打怪之路 Day 15:二叉树解题的思维模式 —— 遍历、分解问题

今日题目&#xff1a; 226. 翻转二叉树101. 对称二叉树114. 二叉树展开为链表 目录 LC 226. 翻转二叉树 【easy】LC 101. 对称二叉树 ⭐⭐⭐LC 114. 二叉树展开为链表 ⭐⭐⭐ 今天的题目主要是对二叉树递归遍历的应用&#xff0c;东哥带你刷二叉树&#xff08;思路篇&#xff0…

java接口(interface)的编写以及实现(implements)

在Java中编写接口可以按照以下步骤进行操作&#xff1a; 首先定义一个新的文件并使用.java为后缀名。这将成为我们要创建的接口所在的类文件。 在该文件中&#xff0c;使用关键字 interface 来声明一个接口。例如&#xff1a;public interface MyInterface { }。 在接口内部&…

谈谈伦敦金操作策略中如何加码

在伦敦金操作策略中应该涉及加码的问题&#xff0c;什么叫加码呢&#xff1f;加码是指一笔伦敦金交易盈利以后&#xff0c;在市场中再注入资金进行加仓。在有利于自己的情况下&#xff0c;我们仓位越重&#xff0c;累积的盈利越多。而且这是在已经盈利的基础上加码&#xff0c;…

Java 学习和实践笔记(28):equals方法的使用

equals() 是Object类里的一个方法。而Object类是所有类的父类&#xff0c;所有的Java对象都拥有Object类的属性和方法。一切类&#xff0c;如果在类的声明中未使用extends&#xff0c;则默认继承Object类。如果声明了&#xff0c;那么Object类就变成该类的父类的父类的...类&am…

python+django高校澡堂洗浴浴室预约签到管理系统8d8c

本系统在设计过程中&#xff0c;高校洗浴管理系统的出现就有很大的需求。该系统可以很好地解决这些麻烦和问题。 很好地发挥了该开发方式的优势&#xff0c;让实现代码有了良好的可读性&#xff0c;而且使代码的更新和维护更加的方便&#xff0c;操作简单&#xff0c;对以后的维…

带你详细理解数组与指针(包含二维数组)

作者博客主页&#xff1a;谦逊码农的旅程 1. sizeof中单独放一个数组名&#xff0c;此时的数组名表示整个数组。 2. &数组名&#xff0c;表示整个数组的地址。 3. 在 C 语言中&#xff0c;变量的地址通常是由一个指针来表示&#xff0c;而指针的大小取决于计算机架构和操…

MySQL·SQL优化

目录 一 . 前言 二 . 优化方法 1 . 索引 &#xff08;1&#xff09;数据构造 &#xff08;2&#xff09;单索引 &#xff08;3&#xff09;explain &#xff08;4&#xff09;组合索引 &#xff08;5&#xff09;索引总结 2 . 避免使用select * 3 . 用union all代替u…

Linux之cd、pwd、mkdir 命令

cd命令&#xff0c;切换目录 1&#xff09;当Linux终端&#xff08;命令行&#xff09;打开的时候&#xff0c;会默认以用户的HOME目录作为当前的工作目录。 2&#xff09;我们可以通过cd命令&#xff0c;更改当前所在的工作目录。 3&#xff09;cd命令来自英文&#xff1a;C…

C#使用Stack类进行堆栈设计

目录 一、涉及到的知识点 1.栈定义 2.Stack类 二、 使用Stack类进行堆栈设计 1.创建一个新的Stack实例 2.然后&#xff0c;可以使用Push方法将元素添加到堆栈中 3.使用Pop方法从栈顶删除一个元素 4.使用Peek方法查看堆栈顶部的元素 三、实例 一、涉及到的知识点 1.栈…

java中的死锁问题

什么是死锁&#xff1f; 当多个线程持有不同的资源&#xff0c;并且互相等待对方释放资源时&#xff0c;就会导致死锁的发生。在死锁情况下&#xff0c;各个线程都无法继续向前执行&#xff0c;导致程序无法继续运行。 死锁的四个条件&#xff1f; 互斥条件&#xff1a;线程…

3.6消息队列

实现消息队列实现AB进程对话。 a.A进程发送一句话后&#xff0c;B进程接收到打印。然后B进程发送一句话&#xff0c;A进程接收后打印 b.重复上述步骤。直到AB接收或者发送完quit后&#xff0c;结束AB进程 A: #include <stdio.h> #include <sys/types.h> #inclu…

使用nvidia-ml-py事实监控GPU状态

平时监控GPU状态最常用的是watch配合nvidia-smi指令&#xff0c;但有时可能不仅仅需要监控&#xff0c;还需要记录状态数据&#xff0c;比如GPU的显存变化以及利用率变化等等。本文提供了一个使用nvidia-ml-py包编写的简易Demo&#xff0c;该Demo能够实现简易版的nvidia-smi功能…

C++之获取Windows系统信息

目录 1. 操作系统版本 2. 获取CPU信息 3. 获取内存信息 4. 获取硬盘信息 5.获取网络接口信息 6.获取计算机名称、用户名 在C中&#xff0c;你可以使用Windows API函数来获取Windows系统的各种信息。以下是一些常见的API函数和示例代码&#xff0c;用于获取Windows系统信息…

⁴ 细说IT从业者35岁,真的是职业的转折点吗

IT从业者如何跨过35岁职业门槛是一个很重要的问题。 一 虽然年龄可能会成为一些公司在招聘过程中的考虑因素&#xff0c;但是有一些方法可以帮助你克服这个挑战并继续在IT行业中发展。 首先&#xff0c;持续学习和自我提升非常重要。随着科技的不断发展&#xff0c;IT行业也在不…

STM32使用标准库编写外部时钟控制oled显示计数(proteus仿真)

这节课的结果是在上节课的基础上更改的&#xff1a;电路图为&#xff1a;用一个开关来模拟外部时钟的高低电平的变化。 当然也可以配置一个外部时钟来模拟&#xff0c;也是可以的&#xff1a; 由于这节课的代码是在上节课的基础上有一点修改而来的&#xff0c;所以就只把更改的…