【C++】哈希的应用:位图和布隆过滤器

news2024/12/30 1:36:24

目录

  • 1. 位图
    • 1.1 位图的概念
    • 1.2 位图的结构
    • 1.3 位图的实现
  • 2. 布隆过滤器
    • 2.1 概念
    • 2.2 结构
    • 2.3 布隆过滤器的实现


1. 位图

1.1 位图的概念

💭位图bitset)是一种基于哈希思想设计的数据结构,其功能主要用于判断数据是否已存在。适用于海量数据,且数据不重复的场景。

以一个问题引入:给40亿个不重复的无符号整数,无序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。

🔎暴力查找法:遍历所有数据,查找目标数是否存在于数据中。但是,因为数据巨大,遍历效率会很慢。
🔎二分查找法:但要先排序,排序要在内存中排,40亿个整数大约要占16G空间(推导过程如下图),内存空间不足。

在这里插入图片描述

因此以上两种方法都不适应,此时就要上位图了。


1.2 位图的结构

在这里插入图片描述

⭕位图以一个个比特位组成,每个比特位代表一种状态,且每个位都有一个下标。位图中的状态为1表示对应下标的数据存在,为0表示对应下标的数据不存在。

举个栗子:假设有如下一组数据,用位图表示

int arr = {3,11,8,23,12,9,0,19,17}; 

在这里插入图片描述


1.3 位图的实现

namespace ckf
{
	template <size_t N> // 范围 0~N
	class bitset
	{
	public:
		bitset()
		{
			_bits.resize(N / 8 + 1, 0);
		}

		// 给第x位置1
		void set(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			_bits[i] |= (1 << j);
		}
		
		// 给第x位置0
		void reset(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			_bits[i] &= ~(1 << j);
		}
		
		// 检测第x位是否存在
		bool test(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;

			return _bits[i] & (1 << j);
		}

	private:
		vector<char> _bits;
	};
}

2. 布隆过滤器

2.1 概念

💭位图只能应用于整数,如果想存储其他类型应该怎么办呢?用布隆过滤器

布隆过滤器(Bloom Filter)是一种快速、高效的数据结构,用于检测一个元素是否属于某个集合。它通过使用一个位数组和多个哈希函数来判断一个元素是否可能在集合中。

布隆过滤器的主要应用是在大规模数据集合中判断某个元素是否存在,比如网络爬虫中URL的去重、大型分布式系统中的缓存机制等。布隆过滤器可以节省存储空间,因为它不需要将元素本身存储在数据结构中,只需要存储其哈希值。

但是,布隆过滤器也存在一些缺点,如误判率高和无法删除元素等。在使用时需要根据具体场景进行权衡和选择。

2.2 结构

在这里插入图片描述

⭕假设向布隆过滤器插入了"left""going"三个字符串,分别通过两个哈希函数映射到位图数组上。而"right","find"此时并不在布隆过滤器中,但是由于哈希函数映射与已在的字符串相同,导致它们在位图上的比特位存在1,这就是布隆过滤器的误判。

得出结论:布隆过滤器中,元素通过哈希函数映射后,若每个位都为1,则不一定存在(可能误判),若存在一个位为0,则该元素一定不存在。因此布隆过滤器只能判断元素不存在,因此起到了过滤的作用。

  • 如何选择哈希函数个数和布隆过滤器长度
    参考文章:详解布隆过滤器的原理,使用场景和注意事项

2.3 布隆过滤器的实现

// N为最多能插入的数据个数
template <size_t N, size_t X = 5,class K = string, 
	class HashFunc1 = BKDRHash<K>, 
	class HashFunc2 = SDBMHash<K>, 
	class HashFunc3 = RSHash<K>>
class bloom_filter
{
public:
	void set(const K& key)
	{
		size_t len = N * X;

		size_t hash1 = HashFunc1()(key) % len;
		size_t hash2 = HashFunc2()(key) % len;
		size_t hash3 = HashFunc3()(key) % len;

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

	bool test(const K& key)
	{
		size_t len = N * X;

		size_t hash1 = HashFunc1()(key) % len;
		if (!_bs.test(hash1))
		{
			return false;
		}

		size_t hash2 = HashFunc2()(key) % len;
		if (!_bs.test(hash2))
		{
			return false;
		}

		size_t hash3 = HashFunc3()(key) % len;
		if (!_bs.test(hash3))
		{
			return false;
		}

		return true;
	}

private:
	bitset<N* X> _bs;
};

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

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

相关文章

【设计模式】模板方法模式--让你的代码更具灵活性与可扩展性

文章目录 前言模板方法模式的定义核心组成模板方法模式与其他设计模式的区别 代码实现抽象类具体类Client 经典类图spring中的例子 总结 前言 在软件开发中&#xff0c;设计模式是一种经过实践检验的、可复用的解决方案&#xff0c;它们可以帮助我们解决某一特定领域的典型问题…

【2023 · CANN训练营第一季】应用开发深入讲解——第一章 模型转换(1)

学习目标 学习资源 1.模型转换 模型转换基础 在线课程 文档AIPP功能说明 文档 应用开发&#xff08;初级&#xff09; 课程目标&#xff1a; 了解AscendCL的使用场景、基本概念、基本开发流程。 学会使用AscendCL接口开发基础推理应用&#xff0c;应用中包含对图片的基本处理…

javaScript常见面试题(二)

一、浅拷贝和深拷贝 浅拷贝&#xff1a;&#xff08;1&#xff09;对于基本数据类型&#xff0c;拷贝的是值&#xff0c;修改的时候数据互不影响&#xff1b;&#xff08;2&#xff09;对于引用数据类型&#xff0c;拷贝的是在堆内存中存储的内存地址&#xff0c;修改的时候&a…

mapreduce基础: 手写本地wordcount案例

文章目录 一、源代码1. WordCountMapper类2. WordCountReducer类3. WordCountDriver类 二、运行截图 一、源代码 1. WordCountMapper类 package org.example.wordcount;import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apac…

yum库和nfs共享服务

yum库 redhat&#xff0c;centos用的是.rpm的包&#xff0c;用yum解决依赖包关系下载 ubuntu&#xff0c;debian用的是.deb的包&#xff0c;用apt解决依赖包的关系下载 yum软件仓库的提供方式 FTP服务: ftp://… HTTP服务: http://…或者https&#xff1a;//… 本地目录: fi…

母婴品牌内容输出怎么做?“四板斧”送你

新媒体时代&#xff0c;信息大爆炸&#xff0c;人们的注意力有限&#xff0c;有噱头和亮点的内容才能博得注意&#xff0c;成为用户关注的焦点。 母婴行业重视品牌效益和产品的质量&#xff0c;毕竟类似“三聚氰胺”的惨剧谁也不希望再发生。母婴产品的质量依赖技术和生产线支…

C语言从入门到精通第9天(循环结构的使用)

循环结构的使用 while语句do-while语句for语句嵌套循环 循环结构可以重复的执行一段代码块&#xff0c;在C语言中提供了三种不同类型的循环结构&#xff1a;for、while和do-while。 while语句 语法&#xff1a; while(表达式){ 语句&#xff1b; } 如果表达式为真则执行结构体…

并发编程学习笔记

为什么学&#xff1f; 只要去做一个技术含量稍微好点的系统&#xff0c;并发包下面的东西是很容易会要用到的 synchronized(Object){ } 主要是用来给对象加锁 synchronized底层原理 首先监视器的计数器是0&#xff0c;然后线程一访问&#xff0c;会将值改为1&#xff0c;…

[Gitops--4] OpenELB

OpenELB OpenELB是一个开源的负载均衡器,功能和metalLB类似 OpenELB主要两种工作模式: Layer2和BGP模式.目前OpenELB的BGP不支持ipv6 OpenELB核心思想就是通过某种方式将特定的VIP的流量引导k8s集群中,然后通过Kube-proxy将流量转发到后面的特定服务. 1. OpenELB介绍 1.1 La…

对于python文件,敲下回车后发生了什么

引言 我们常说 Python 一是门解释型语言&#xff0c;只需要敲下 python code.py就可以运行编写的代码&#xff0c;而无需使用类似于 javac 或者 gcc 进行编译。那么&#xff0c;Python 解释器是真的一行一行读取 Python 源代码而后执行吗? 实际上&#xff0c;Python 在执行程序…

为什么要进行倾斜摄影三维模型的顶层合并?

为什么要进行倾斜摄影三维模型的顶层合并&#xff1f; 1、倾斜摄影三维模型顶层合并的重要性 倾斜摄影三维模型的顶层合并是指将拍摄同一区域的多个倾斜角度的影像进行融合&#xff0c;生成一个连续的、完整的三维地理信息数据。其原因主要有以下几点&#xff1a; &#xff0…

关于倾斜摄影三维模型轻量化数据大小和质量关系分析

关于倾斜摄影三维模型轻量化数据大小和质量关系分析 倾斜摄影三维模型轻量化是一种常用的技术&#xff0c;通过对原始三维模型数据进行压缩和简化&#xff0c;减小其数据大小&#xff0c;从而提高数据传输和展示效率。然而&#xff0c;轻量化过程中可能会对数据质量产生影响。以…

性能测试——安装Loadrunner11.0的详细步骤

一、下载Loadrunner11.0版本 去相关网站下载即可 二、安装 &#xff08;windows与虚拟机上安装操作大相径庭&#xff09; 1、将ISO文件导入&#xff0c;打开光驱&#xff0c;运行“setup.exe“ 2、点击安装&#xff0c;部分机器会提示缺少“Microsoft Visual C 2005 SP1运行组…

有效的字母异位词

给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetco…

Java 将json中key值中带有下划线的部分转为驼峰格式

一、背景说明 在开发过程中&#xff0c;有时会遇到第三方厂商提供的接口返回结果不是严格按照驼峰命名&#xff0c;需要将其中带有下划线的字段进行格式化转换为驼峰命名。 如下图中的self_auth、user_id、user_name、creator_name 和 others_auths 等 key 值。 如果是对 JS…

Mysql 45讲和45问笔记(未完待续0203/04/24)

一、mysql 45讲 1&#xff09;索引的本质讲解 定义解释 所以是帮助Mysql高效获取数据的排好序的数据结构 索引数据结构 ①二叉树 ②红黑树 ③Hash表 ④B-Tree 原理讲解 可以看到右边的数据结构里面&#xff0c;是按照k-v来存数据结构的&#xff0c;key是col2的字段&#xf…

【Linux】线程-线程概念

线程概念 什么是线程线程的优点和缺点线程的用途和线程异常线程与进程的区别 什么是线程 实际上&#xff0c;线程是一个进程内部的控制序列&#xff0c;一个程序的一个执行线路就是一个线程。 并且一个进程中至少有一个线程&#xff0c;本质上&#xff0c;一个进程内部如果有多…

6. 树的入门

6. 树的入门 之前我们实现的符号表中&#xff0c;不难看出&#xff0c;符号表的增删查操作&#xff0c;随着元素个数N的增多&#xff0c;其耗时也是线性增多的&#xff0c;时间复杂度都是O(n),为了提高运算效率&#xff0c;接下来我们学习树这种数据结构。 6.1 树的基本定义 …

MybatisPlus-入门项目搭建、SQL日志打印、实体类注解、简单持久层操作

Mybatis-Plus mybatis plus概述 ​ Mybatis Plus &#xff08;opens new window&#xff09;简称 MP&#xff0c;它是一个MyBatis 的增加工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 Mybatis Plus官网&#xff1a;https://…

拉格朗日函数对偶问题、KKT条件

一、概念介绍 KKT最优化条件是Karush(1939)以及Kuhn和Tucker(1951)先后独立发表出来的&#xff0c;但在Kuhn和Tucker发表之后才逐渐受到重视&#xff0c;因此多数情况下记载成库恩-塔克条件(Kuhn-Tucker conditions)。先介绍几个优化的概念。 1.1 优化 最优化问题&#xff0…