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

news2024/11/27 22:37:53

位图和布隆过滤器

  • 一,位图
    • 1. 实现
    • 2. 位图的应用
  • 二,布隆过滤器
    • 1. 使用场景
    • 2. 模拟实现
  • 三,海量数据面试题
    • 哈希切分
  • 四,总结

这一节我们来看哈希的应用

一,位图

先来看一个面试题
在这里插入图片描述
这里如果用unordered_set来解决,是不可取的,因为一个整型4个Byte,40亿个整型那就是16个G,把这16个G直接放进内存是不合理的,所以就要用到位图。
在这里插入图片描述

位图和哈希表相比,就是将每个数据元素映射到每一个比特位上。适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

1. 实现

位图的实现比较简单,下面是位图bitset的一些常用接口:
在这里插入图片描述
首先我们要构造位图,确定好要开的空间大小
这里的构造需要传入所需要的比特位数,然后我们在实现时根据传入的N来确定相应的比特位
在这里插入图片描述
这里我们可以先写出bitset的框架:

template<size_t N>//非类型模板参数---表示需要多少个比特位去映射
class bitset {
public:
	bitset() {
		//构造函数根据需要的比特位来开相应的数组
		_bits.resize((N >> 5) + 1, 0);//除以2的5次方相当于右移5位
	}
	//...
private:
	vector<int> _bits;
};

这里我们也是只模拟实现主要的接口:
在这里插入图片描述
set的作用是将一个整型放入位图中,映射的时候我们先找到要映射的是第几个字节,然后再计算这个字节的第几个比特位,将这个比特位置为1即可

在这里插入图片描述

reset的作用是将数据从位图中删除,也就是将映射的比特位置为0

void set(size_t x) {//将映射到的位置置为1
	size_t i = x / 32;//i表示映射在数组的第几个整型中
	size_t j = x % 32;//j表示映射在第i个整型的第j位上
	_bits[i] |= (1 << j);//将映射到的位置置为1---用相应的数去 或等 (任何数和1或都为1,和0或为任何数)
}

void reset(size_t x) {//将映射的位置置为0
	size_t i = x / 32;
	size_t j = x % 32;
	_bits[i] &= ~(1 << j);//将映射的位置置为0---将相应的数取反去 与等 (任何数和1与为如何数,和0与都为0)
}

位图解决的是在不在的问题,当然位图这种结构也有一个扩展的问题,就是找到第一次出现的数的这类问题,对于这类问题,其实就是用两个位图来存放一个数
在这里插入图片描述
具体的代码可以进入我的gitee仓库查看: 位图的实现

2. 位图的应用

对于位图来说,其只能存储整型的数据,所以其常见的应用就是如下几个:
在这里插入图片描述

二,布隆过滤器

1. 使用场景

对于位图而言,其只能处理整型的数据,如果要处理字符串类型呢,就无法处理了

我们如果简单地将字符串转换为整型,再映射到对应的位,那么就会出现多个字符串映射到同一个位的问题,因为整型最大只有32位,但是字符串可以有很多位
在这里插入图片描述
为了解决这样的问题我们可以让一个字符串映射到多个比特位上
在这里插入图片描述
这样的结构也会导致判断一个字符串不在是准确的,因为只要有一个比特位为0就是不在,判断在是不准确的,因为哈希函数存在误判。

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

至于为什么叫布隆过滤器,我们可以看下面的使用场景进行理解:
假设有一个注册页面需要你来创建用户名,如果这个用户名已经被创建,则需要换一个名称,那么面对大量的数据情况下,如果查找这个创建的用户名是否已经被申请了呢?总不可能每次都在后台的服务器上一个个查找吧,这时就可以借助布隆过滤器了,如果查找这个名称存在,则不可以创建,如果不在,则可以创建。这种场景下是允许误判的,因为判断一个不在的比误判一个存在的要合理
在这里插入图片描述

2. 模拟实现

下面我们来模拟实现一下,布隆过滤器底层用的其实也是位图,所以实现时我们直接用位图的接口即可
这里默认处理的类型是string,所以要有对应的哈希函数来将字符串转换为整型,这里我们直接用三种哈希函数来转换。

//这三个哈希函数造成的哈希冲突是最少的
struct BKDRHash
{
	size_t operator()(const string& key)
	{
		// BKDR
		size_t hash = 0;
		for (auto e : key)
		{
			hash *= 31;
			hash += e;
		}

		return hash;
	}
};

struct APHash
{
	size_t operator()(const string& key)
	{
		size_t hash = 0;
		for (size_t i = 0; i < key.size(); i++)
		{
			char ch = key[i];
			if ((i & 1) == 0)
			{
				hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
			}
			else
			{
				hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
			}
		}
		return hash;
	}
};

struct DJBHash
{
	size_t operator()(const string& key)
	{
		size_t hash = 5381;
		for (auto ch : key)
		{
			hash += (hash << 5) + ch;
		}
		return hash;
	}
};


template<size_t N, class K = string,
class Hashfunc1 = BKDRHash,
class Hashfunc2 = APHash,
class Hashfunc3 = DJBHash>//这里默认处理的是sting字符串,三个仿函数是哈希函数,将string映射成整型
class BloomFilter {
public:
	void set(const K& key)
	{
		//将字符串经过哈希得到三个整型
		size_t hash1 = Hashfunc1()(key) % N;//仿函数匿名对象,%N是为了不超出N
		size_t hash2 = Hashfunc2()(key) % N;
		size_t hash3 = Hashfunc3()(key) % N;

		//再将这三个整型分别映射到三个比特位
		_b.set(hash1);
		_b.set(hash2);
		_b.set(hash3);
	}
private:
	bitset<N> _b;
};

完整代码可以参考这里:布隆过滤器

三,海量数据面试题

哈希切分

有这样一个问题
在这里插入图片描述
这里有两个100亿的查询字符串query,是不可能将这两个字符串放进内存直接查询的,所以就要做到哈希切割
在这里插入图片描述
这样切分后,每个小文件都是相同的数据元素,找交集时会在相同的文件中查找

但是如果切分后的小文件还是很大怎么办

切分后的小文件很大的原因有两个
1.一个文件中都是相同的query
2.这个文件中很多不同的query
如果遇到这种问题,则继续将这个小文件放入set中,如果是第一种情况,那么在放入set中时,重复的元素不会被存入
如果是第二种情况,则继续进行哈希切分处理。

四,总结

哈希这部分我们也算是讲解完了,哈希的用途还是非常的广。希望大家可以对哈希有一个深入的理解。C++学到这里其实也走过了大部分了,但是在这里我想说基础还是很重要的,基础越牢固,后面的学习才会更快。希望大家都可以打好基础,对C++有深入的学习。

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

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

相关文章

程序员如何搞副业

目录 1.概述 2.个人项目开发 3.在线教育和培训 4.技术博客和内容创作 1.概述 程序员通过副业实现个人价值最大化和增加收入的途径多种多样&#xff0c;以下是一些方法&#xff1a; 自由职业: 程序员可以在业余时间提供自由职业服务。包括为客户开发软件、网站或应用程序、…

初学python记录:力扣2009. 使数组连续的最少操作数

题目&#xff1a; 给你一个整数数组 nums 。每一次操作中&#xff0c;你可以将 nums 中 任意 一个元素替换成 任意 整数。 如果 nums 满足以下条件&#xff0c;那么它是 连续的 &#xff1a; nums 中所有元素都是 互不相同 的。nums 中 最大 元素与 最小 元素的差等于 nums.…

java 开发环境配置 JAVA_HOME 和 MAVEN_HOME

java 开发环境配置 JAVA_HOME 和 MAVEN_HOME 介绍JAVA_HOMEMAVEN_HOME 配置环境1. 创建Java Home2. 创建Maven Home3. 设置环境变量4. 验证安装 没有 Maven 看这里 介绍 在Java和Maven的开发环境中&#xff0c;JAVA_HOME和MAVEN_HOME是非常重要的环境变量&#xff0c;它们帮助…

iOS 开发中上传 IPA 文件的方法(无需 Mac 电脑

引言 在 iOS 开发中&#xff0c;将 IPA 文件上传到苹果开发者中心是一个重要的步骤。通常情况下&#xff0c;我们需要使用 Mac 电脑上的 Xcode 或 Application Loader 工具来完成这个任务。然而&#xff0c;如果你没有 Mac 电脑&#xff0c;也没有关系&#xff0c;本文将介绍一…

JAVA毕业设计135—基于Java+Springboot+Vue的服装商城(源代码+数据库+万字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的服装商城(源代码数据库万字论文)135 一、系统介绍 本项目前后端分离&#xff0c;分为管理员、用户两种角色 1、用户&#xff1a; 注册、登录、服装购买、…

Centos7搭建 SkyWalking 单机版

介绍 Skywalking是应用性能监控平台&#xff0c;可用于分布式系统&#xff0c;支持微服务、云原生、Docker、Kubernetes 等多种架构场景。 整体架构如图 Agent &#xff1a;在应用中&#xff0c;收集 Trace、Log、Metrics 等监控数据&#xff0c;使用 RPC、RESTful API、Kafk…

解决PyCharm更新到2024.1版本后不能运行项目的问题

先来看看这个问题的表现吧。 1、运行和调试按钮是灰色的&#xff0c;并且显示编辑器中的文件不可运行&#xff0c;代码也是灰色的&#xff0c;还有我们的python文件的图标和文本文件的图标一样。 当然右键也是没有运行、调试选项。 2、无法创建新的项目和py文件&#xff0c;能…

Teachable Machine模型之TensorFlow使用篇

前言: 使用在teachable machine训练的h5格式模型 tensorflow使用篇 1. 使用teachable machine训练模型 地址: 传送门, 需要梯子翻一下 训练后, 导出的时候可以选择三种类型 导出模型文件 converted_keras.zip (py版) 解压后得到 2. py项目中使用模型 根据你当时使用tea…

简介:基于Web的产品3D

基于 Web 的产品 3D 通过可视化界面获得各种选项来个性化他们的产品&#xff0c;例如颜色、材料、尺寸、文字、徽标、零件等。 在过去几年中&#xff0c;随着 3D 建模和渲染软件的出现&#xff0c;3D 渲染现在更常用于营销和促销目的。设计师、制造商和营销人员使用 3D 产品渲…

20240408通过win32diskimager给TF卡写入Ubuntu Core 16.04

20240408通过win32diskimager给TF卡写入Ubuntu Core 16.04 2024/4/8 20:48 IMG固件使用&#xff1a;h3-eflasher-friendlycore-xenial-4.14-armhf-20210618.img 固件不能放倒中文目录里/只能放到英文目录内&#xff01; 【也不能放到网络磁盘里】映射网络驱动器&#xff01; Wi…

大模型日报|今日必读的7篇大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.CT-LLM&#xff1a;仅 20 亿参数&#xff0c;基于中文的大型语言模型 来自开源研究社区 Multimodal Art Projection、复旦大学和香港科技大学的研究团队及其合作者&#xff0c;推出了一个 20 亿参数的大型语言模型…

c++配置libtorch

这里写目录标题 LibTorch下载Vistual Studio环境配置C部署Libtorch出现问题、错误汇总检测环境是否配置成功 LibTorch下载 安装LibTorch非常简单&#xff0c;只需要从其官网选择相应的版本即可&#xff0c;具体页面如下图所示。 如果需要加载PyTorch训练的模型文件&#xff0…

Centos中一些有趣的命令

目录 1.sl 小火车 2. cowsay 会说话的牛 3.toilet/figlet 图形化输出 4.aafire 小火焰 5.linux_logo 显示系统logo 1.sl 小火车 yum install sl 2. cowsay 会说话的牛 yum install cowsay 3.toilet/figlet 图形化输出 yum install toilet yum install figlet 4.aafire 小火…

电子电路中,MOS管的开启电压取多少最为合适呢?

电路中&#xff0c;MOS管的开启电压取多少最为合适呢&#xff1f; 比如&#xff1a; 某Nmos VGS范围为正负20V 栅极阈值电压&#xff08;VGSth&#xff09;最小为0.8V&#xff0c;最大为1.5V 那么此时的Mos管栅极电压取多少最为合适&#xff1f; 在电路中&#xff0c;MOS管的开…

通过Golang获取公网IP地址

在Go语言中&#xff0c;获取当前的外网&#xff08;公网&#xff09;IP地址可以通过多种方法实现。其中一种常见的方法是通过访问外部服务来获取。这些服务可以返回访问者的公网IP地址&#xff0c;例如 httpbin.org/ip 或 ipify.org。下面是一个简单的例子&#xff0c;展示了如…

汇编语言程序设计实验五 条件转移指令

实验目的和要求 (1) 编写实验任务要求的两个程序。 (2) 写出调试以上程序&#xff0c;即修改程序参数&#xff0c;检查结果的操作方法。 (3) 熟悉源程序汇编、连接命令的使用方法即要回答的内容。 实验环境 DOSBOX 实验内容与过程 验证以下程序 16进制数…

JS 轮播图点击左右切换

点击左右按钮实现轮播图切换图片 style&#xff1a; *{margin: 0;padding: 0;margin: auto;}#img1{width: 300px;height: 300px;position: relative;}#butto1{width: 50px;height: 100px;font-size: 50px;border: none;background-color: hsla(0, 0%, 0%, 0.2);position: abs…

CS162 Operating System笔记

What is an Operating System? it’s typically a special layer of software that provides the application access to hardware resources.So.it’s convenient abs fractions of complex hardware devices.

DVWA-xss储存型及beef下载(kali)

beef下载 apt-get update apt-get install beef-xss 登录网址是 这里的ip为虚拟机的地址 之后会让你设置密码 如果密码和用户不知道在etc/beef-xss/config.yaml可以查看 这是偷cookie的就是代码 这里是可以修改的不修改的话代码是不全的 通过beef拿到了cookies之后在网页…

知名度最高的3款电脑监控软件

知名度最高的3款电脑监控软件 公司电脑监控软件是一种安装在员工电脑上的软件&#xff0c;主要用于监控和管理员工的电脑屏幕操作、网络行为以及文件操作等。这种软件有助于企业提高员工的工作效率&#xff0c;保护公司的数据安全&#xff0c;并维护公司的IT健康环境。 市面有…