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;
		//检查三个位置是否都为1
		size_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;
}

        运行结果:

结语 

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为OD机试“HJ5 进制转换”Java编程解答

描述 写出一个程序&#xff0c;接受一个十六进制的数&#xff0c;输出该数值的十进制表示。 数据范围&#xff1a;保证结果在 1≤n≤231−1 输入描述&#xff1a; 输入一个十六进制的数值字符串。 输出描述&#xff1a; 输出该数值的十进制字符串。不同组的测试用例用\…

2024最新外贸建站:WordPress搭建外贸独立站零基础教程

想与外国人做生意有多种方式&#xff0c;一些朋友选择在跨境电商平台上开店如&#xff08;亚马逊&#xff09;&#xff0c;而另一些朋友则决定建立自己的外贸独立站点。本篇教程主要说的是第二种方式如何快速建立自己的外贸独立站&#xff01;通过学习这篇外贸建站教程&#xf…

VSCode安装与使用

1、下载地址&#xff1a;Documentation for Visual Studio Code 在 VS Code 中使用 Python - 知乎 (zhihu.com) 自动补全和智能感知检测、调试和单元测试在Python环境(包括虚拟环境和 conda 环境)之间轻松切换 在 VS Code 中安装插件非常的简单&#xff0c;只需要打开 VS Code…

机器学习-面经(part7、无监督学习)

机器学习面经系列的其他部分如下所示&#xff1a; 机器学习-面经&#xff08;part1&#xff09; 机器学习-面经(part2)-交叉验证、超参数优化、评价指标等内容 机器学习-面经(part3)-正则化、特征工程面试问题与解答合集机器学习-面经(part4)-决策树共5000字的面试问题与解答…

体验Node.js的安装和运行

Node.js概述 Node.js是一个基于Chrome V8引擎的JavaScript运行环境。它允许JavaScript代码在服务器端运行&#xff0c;使得开发人员可以使用同一种语言编写前端和后端的代码。Node.js使用事件驱动、非阻塞I/O模型&#xff0c;使其轻量且高效&#xff0c;非常适合数据密集型的实…

8套成熟在用的三级医院信息化系统源码,HIS、LIS、PACS、智慧导诊、线上预约挂号支付系统源码

8套成熟在用的二级医院、三级医院医院管理系统源码&#xff0c;均有自主知识产权&#xff0c;应用案例&#xff0c;系统稳定运行中。可直接上手项目&#xff0c;支持二次开发 ▶ 一、SaaS模式Java语言开发的云HIS系统源码 在公立二甲医院应用三年&#xff0c;融合B/S版电子病历…

【leetcode C++】电话号码的字母组合

17. 电话号码的字母组合 题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 题目链接 . - 力扣&#xff08;LeetCode&…

java常用数据结构面试题,docker教程学习

前言 JVM对实际简单开发的来说关联的还是不多&#xff0c;一般工作个一两年&#xff08;当然不包括爱学习的及专门做性能优化的什么的&#xff09;&#xff0c;很少有人能很好的去学习及理解什么是JVM&#xff0c;以及弄清楚JVM的工作原理&#xff0c;其实我个人认为这块还是非…

C++学习第七天(string类)

1、学习string的原因&#xff1f; C语言中的字符串 C语言中&#xff0c;字符串是以‘\0’结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;而且底层空间需要用户自己管…

浅析扩散模型与图像生成【应用篇】(七)——Prompt-to-Prpmpt

7. Prompt-to-Prompt Image Editing with Cross Attention Control 本文提出一种利用交叉注意力机制实现文本驱动的图像编辑方法&#xff0c;可以对生成图像中的对象进行替换&#xff0c;整体改变图像的风格&#xff0c;或改变某个词对生成图像的影响程度&#xff0c;如下图所示…

Django 管网项目 三

Django 官网文档 ​​Writing your first Django app, part 2 | Django documentation | Django 本文内容涉及创建视图 View&#xff0c;路由&#xff0c;和模版。并对内容进行渲染。 创建视图 在我们的投票应用中&#xff0c;我们需要下列几个视图&#xff1a; 问题索引页—…

LabVIEW管道缺陷智能检测系统

LabVIEW管道缺陷智能检测系统 管道作为一种重要的输送手段&#xff0c;其安全运行状态对生产生活至关重要。然而&#xff0c;随着时间的推移和环境的影响&#xff0c;管道可能会出现老化、锈蚀、裂缝等多种缺陷&#xff0c;这些缺陷若不及时发现和处理&#xff0c;将严重威胁到…

外包干了10天,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

《程序员的职业迷宫:选择你的职业赛道》

程序员如何选择职业赛道&#xff1f; 大家好&#xff0c;我是小明&#xff0c;一名在编程迷宫中探索的程序员。作为这个庞大迷宫的探险者&#xff0c;我深知选择适合自己的职业赛道有多么重要。今天&#xff0c;我将分享一些关于如何选择职业赛道的心得&#xff0c;希望能够帮…

JWT令牌实现登陆校验

一、JWT出现的背景 jwt令牌出现的背景&#xff0c;比如我们通过一个路由访问网站的时候&#xff0c;有些游客在知道url的情况下会跳过用户登录直接访问其他网页&#xff0c;这样不仅在逻辑上说不通&#xff08;我没登陆咋就能使用其他功能&#xff1f;&#xff09;还会造成信息…

指针乐园--下

大家好这里是指针乐园下&#xff0c;下面我们开始喽&#xff01;&#xff01; 文章目录 目录 文章目录 前言 一、字符以及数组指针 二、函数指针变量以及函数指针数组 函数指针变量的使⽤ 通过函数指针调⽤指针指向的函数。 函数指针数组 总结 前言 我们今天会学习数组指针&…

LeNet训练集详细实现

一、下载训练集 导包 import torch import torchvision import torch.nn as nn from model import LeNet import torch.optim as optim import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as npToTensor()函数&#xff1a; 把图像…

npm 私服以及使用

在工作中&#xff0c;公司有很多内部的包并不希望发布到npm官网仓库&#xff0c;因为可能涉及到一些私有代码不能暴露。对于前端来讲&#xff0c;这时就可以选择在公司内网搭建npm私有仓库。当前比较主流的几种解决方案&#xff1a;verdaccio、nexus、cnpm。大家可以按照自己的…

限时特惠,立即购买CST电磁仿真软件,享受超值优惠与高质量服务

在电磁仿真领域&#xff0c;CST软件以其卓越的性能和广泛的应用成为了行业内的佼佼者。现在&#xff0c;我们非常高兴地宣布&#xff0c;为庆祝CST软件的持续创新与客户支持&#xff0c;我们推出限时特惠活动&#xff01;&#xff08;联系CST软件中国区代理亿达四方&#xff0c…

RabbitMQ如何保证消息不丢

如何保证Queue消息能不丢呢&#xff1f; RabbitMQ在接收到消息后&#xff0c;默认并不会立即进行持久化&#xff0c;而是先把消息暂存在内存中&#xff0c;这时候如果MQ挂了&#xff0c;那么消息就会丢失。所以需要通过持久化机制来保证消息可以被持久化下来。 队列和交换机的…