位图/布隆过滤器

news2024/11/19 15:39:16

一、位图

1.1位图的概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

1.2位图的实现

    template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			//需要N个比特位,一个字节四个比特位,四个字节32个比特位,所以要除以32,向上取整。
			_a.resize(N / 32 + 1);
		}
		void set(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			_a[i] |= (1 << j);
		}
		void reset(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			_a[i] &= ~(1 << j);
		}
		bool test(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			return _a[i] & (1 << j);
		}
	private:
		vector<int> _a;
	};

二、布隆过滤器

2.1布隆过滤器的概念

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

2.2布隆过滤器的插入

布隆过滤器的底层是位图

如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,则上图转变为:

我们现在再存一个值 “tencent”,如果哈希函数返回 3、4、8 的话,图继续变为:

可以看到下标为4的位置被覆盖了。

2.3布隆过滤器的查找

布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特位一定为1。所以可以按照以下方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为
零,只要有一个为零,代表该元素一定不在哈希表中,否则可能在哈希表中。

注意:注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。

如果有一个字符串“kkkkkkk” 哈希函数返回的值为1,4,7,而此时1,4,7位置的值为1,刚好和其
他元素的比特位重叠,那么查找字符串“kkkkkkk”的结果为存在,但是实际上这个字符串不存在。所以判断存在会出现误判。

2.4布隆过滤器的删除

布隆过滤器不支持删除操作,因为如果有两个元素的哈希值重叠,那么删除一个元素会影响另一个元素。

2.5布隆过滤器的优点

相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数,时间复杂度为O(K), (K为哈希函数的个数,一般比较小)。另外,散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。

布隆过滤器可以表示全集,其它任何数据结构都不能;

使用同一组散列函数的布隆过滤器可以进行交、并、差运算

2.5布隆过滤器的缺点

随着存入的元素数量增加,误算率随之增加。

另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。然而要保证安全地删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面。这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。

在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。

设m为布隆过滤器的大小,n为插入元素的个数,满足 m=4.3*n 综合而言更好。

2.6布隆过滤器的模拟实现

//针对于字符串来说,常用的三个哈希函数
template<class T = string>
struct BKDRHash
{
	size_t operator()(const T& str)
	{
		size_t hash = 0;
		for(auto ch : str)
		{
			hash = hash * 131 + ch;   // 也可以乘以31、131、1313、13131、131313..           
		}
		return hash;
	}
};

template<class T = string>
struct APHash
{
	size_t operator()(const T& str)
	{
		size_t hash = 0;
		int i = 0;
		for (auto ch : str)
		{
			
			if ((i & 1) == 0)
			{
				hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
			}
			else
			{
				hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
			}
			++i;
		}
		return hash;
	}
};



template<class T = string>
struct DJBHash
{
	size_t operator()(const T& str)
	{
		if (str.length() == 0)
			return 0;
		size_t hash = 5381;
		for(auto ch : str)
		{
			hash += (hash << 5) + ch;
		}
		return hash;
	}
};


template<size_t N, class T = string, class Hash1 = BKDRHash<T>, 
		class Hash2 = APHash<T>, class Hash3 = DJBHash<T>>
class BloomFilter
{
public:
	void set(const T& str)
	{
		size_t hash1 = Hash1()(str) % N;
		size_t hash2 = Hash2()(str) % N;
		size_t hash3 = Hash3()(str) % N;

		_bs.set(hash1);
		_bs.set(hash2);
		_bs.set(hash3);
	}

	bool Test(const T& str)
	{
		size_t hash1 = Hash1()(str) % N;
		if (_bs.test(hash1) == 0)
			return false;
		size_t hash2 = Hash2()(str) % N;
		if (_bs.test(hash2) == 0)
			return false;
		size_t hash3 = Hash3()(str) % N;
		if (_bs.test(hash3) == 0)
			return false;
		
		return true;//存在误判
	}
private:
	bitset<N> _bs;
};

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

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

相关文章

SpringBoot客户端实现分片、断点上传

客户端的分片上传和断点续传是指将一个文件拆分为多个分片&#xff0c;在网络不稳定或上传中断后&#xff0c;可以从中断处继续上传而不需要重新上传整个文件。 当需要上传大型文件时&#xff0c;客户端的分片上传和断点续传是一种常用的技术。它可以提高上传效率并减少网络中断…

【计算机网络面试题(62道)】

文章目录 计算机网络面试题&#xff08;62道&#xff09;基础1.**说下计算机网络体系结构2.说一下每一层对应的网络协议有哪些&#xff1f;3.那么数据在各层之间是怎么传输的呢&#xff1f; 网络综合4.**从浏览器地址栏输入 url 到显示主页的过程&#xff1f;5.说说 DNS 的解析…

Vscode配置C#编程环境(win10)

目录 1、安装好Vscode 2、下载安装.NetCore SDK 3、配置C#环境 3.1 打开Vscode并下载扩展 3.2 Vscode中打开文件夹并配置环境 3.3 调试运行 1、安装好Vscode 2、下载安装.NetCore SDK 官网如下&#xff0c;下载完成后双击打开一路走到底就行.NetCore SDK官网 软件显示安…

利用freesurfer6进行海马分割的环境配置和步骤,以及获取海马体积

利用freesurfer6进行海马分割的环境配置和步骤 Matlab Runtime 安装1. 运行recon-all&#xff1a;2. 利用 recon-all -s subj -hippocampal-subfields-T1 进行海马分割3. 结束后需要在/$SUBJECTS_DIR/subject/的文件夹/mri路径下输入下面的代码查看分割情况4. 在文件SUBJECTS_D…

连续波雷达相关内容简介

连续波雷达(CW雷达)连续发射高频信号。回波信号被永久接收和处理。 一、未调制连续波雷达 未调制的连续波雷达除了振荡的相位之外没有其他时间参考。它只能用于测量小于波长的距离。以上的一切都极为含糊。因此,它只能用作多普勒雷达或控制已知距离的恒定性。 二、调频连…

VUE3照本宣科——eslint与prettier

VUE3照本宣科——eslint与prettier VUE3照本宣科系列导航 前言一、eslint1.配置文件2.配置规则3.忽略错误 二、prettier三、总结 VUE3照本宣科系列导航 1.VUE3照本宣科——认识VUE3 2.VUE3照本宣科——应用实例API与setup 3.VUE3照本宣科——响应式与生命周期钩子 4.VUE3照本宣…

关于Go语言的底层,Channel

1.Channel 介绍一下Channel&#xff08;有缓冲和无缓冲&#xff09; Go 语言中&#xff0c;不要通过共享内存来通信&#xff0c;而要通过通信来实现内存共享。Go 的CSP(Communicating Sequential Process)并发模型&#xff0c;中文可以叫做通信顺序进程&#xff0c;是通过 gor…

剑指offer——JZ54 二叉树搜索树的第k个节点 解题思路与具体代码【C++】

一、题目描述与要求 二叉搜索树的第k个节点_牛客题霸_牛客网 (nowcoder.com) 题目描述 给定一棵结点数为n 二叉搜索树&#xff0c;请找出其中的第 k 小的TreeNode结点值。 1.返回第k小的节点值即可 2.不能查找的情况&#xff0c;如二叉树为空&#xff0c;则返回-1&#xf…

Sql server 使用DBCC Shrinkfile 收缩日志文件

磁盘空间有限&#xff0c;需要收缩日志文件释放空间。 数据库名称上右击属性->文件,逻辑名称日志文件默认名称为“_log”结尾。 alter database 数据库 set recovery simple dbcc shrinkfile(XXX_log,2,truncateonly) alter database 数据库 set recovery full

webp批量转换为png、jpg工具

webp批量转换为png、jpg工具 链接&#xff1a;https://pan.baidu.com/s/1NZArgbiF88_qBbAIiUR4qQ 提取码&#xff1a;2sqs –来自百度网盘超级会员V5的分享

IO流 之 转换流( InputStreamReader 字节输入转换流 和 OutputStreamWriter 字节输出转换流)

当文本文件和代码的编码不一致时&#xff0c;使用字符流会导致读取出来的文字乱码。如下&#xff1a; 读取文件的编码时GBK编码。 代码的编码时UTF-8的编码。 程序运行出来中文则是乱码。 这里就要使用到转换流了。 字节转换流 InputStreamReader 字节输入转换流 使用步骤…

一文搞懂时间序列ARIMA模型

文章目录 1 ARIMA的定义2 差分(differencing)2.1 Order&#xff1a;差分的阶数2.2 Lag&#xff1a;差分的滞后2.3 滞后运算/滞后算子/延迟算子2.4 关于差分的两个误解 3 ARIMA的平稳性4 ACF与PACF5 时序模型的选择与评估5.1 超参数p、q、d的确定5.2 时间序列的评估指标 1 ARIMA…

Linux自用笔记

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Linux相关 ✨特色专栏&#xff1a; My…

码支付添加银行转账功能,手动回调

在后台中通道列表先加上 路径&#xff1a;【后台】 - > 【通道管理】 - > 【新增】 总后台页面通道类型加上支付类型yh_pay和通道yhzz添加后存到数据库admin_chanel上 修改商户页面的【新增通道】页面 /view/index/channel/index.html 添加一个支付通道 <option…

【算法训练-数组 三】【数组矩阵】螺旋矩阵、旋转图像、搜索二维矩阵

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是螺旋矩阵&#xff0c;使用【二维数组】这个基本的数据结构来实现 螺旋矩阵【EASY】 二维数组的结构特性入手 题干 解题思路 根据题目示例 mat…

【DevOps】搭建你的第一个 Docker 应用栈

搭建你的第一个 Docker 应用栈 1.Docker 集群部署2.第一个 Hello World2.1 获取应用栈各节点所需镜像2.2 应用栈容器节点互联2.3 应用栈容器节点启动2.4 应用栈容器节点的配置2.4.1 Redis Master 主数据库容器节点的配置2.4.2 Redis Slave 从数据库容器节点的配置2.4.3 Redis 数…

sql server查询结果:行转列、XML形式

1.普通查询 SELECT M.name From Menu M INNER JOIN MenuRoleRelation MRR ON M.idmrr.MenuId AND MRR.RoleId1; 结果&#xff1a; 2.做xml字符串返回 最后面加上&#xff1a;FOR XML PATH() 结果&#xff1a; 3.可以改为逗号分隔 SELECT ,M.name From Menu M INNER JOIN Me…

深度学习——深度学习计算一

深度学习——深度学习计算一 文章目录 前言一、层和块1.1. 自定义块1.2. 顺序块1.3. 在前向传播函数中执行代码1.4. 小结 二、参数管理2.1. 参数访问2.1.1. 目标参数2.1.2. 一次性访问所有参数2.1.3. 从嵌套块收集参数 2.2. 参数初始化2.2.1. 内置初始化2.2.2. 自定义初始化 2.…

常用Redis界面化软件

对于Redis的操作&#xff0c;前期有过介绍【Centos 下安装 Redis 及命令行操作】。而在Redis的日常开发调试中&#xff0c;可使用可视化软件方便进行操作。 本篇主要介绍Redis可视化的两款工具&#xff1a;Redis Desktop Manager和AnotherRedisDesktopManager。 1、Redis Desk…

unity 控制玩家物体

创建场景 放上一个plane&#xff0c;放上一个球 sphere&#xff0c;假定我们的球就是我们的玩家&#xff0c;使用控制键w a s d 来控制球也就是玩家移动。增加一个材质&#xff0c;把颜色改成绿色&#xff0c;把材质赋给plane&#xff0c;区分我们增加的白球。 增加组件和脚…