[C++]哈希应用-海量数据处理

文章目录

  • 海量数据处理
  • 前言
  • 哈希切分
    • 问题1:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
    • 问题2:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到top K的IP?
  • 位图应用
    • 问题3:给定100亿个整数,设计算法找到只出现一次的整数?
    • 问题4:给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
    • 问题5:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
  • 布隆过滤器
    • 问题6:给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

海量数据处理

哈希的一大重要运用就是对于大数据的处理,通过本章的学习,将会带您解决如下面试题:

  1. 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
  2. 与上题条件相同,如何找到top K的IP?
  3. 给定100亿个整数,设计算法找到只出现一次的整数?
  4. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
  5. 1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
  6. 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

我们将把上述7个问题分成3个部分:

1~2:哈希切分

3~5:位图应用

6:布隆过滤器

前言

对于占用空间极大的文件,我们按理来说确实可以通过对硬盘进行IO的方式来实现需求(即将数据的处理主要放在硬盘中进行,而非内存),但是需要明确几点:

  1. (主要)内存的IO速度远超硬盘的IO速度,所以单次硬盘IO于多次硬盘IO的速度差别是十分大的
  2. 在硬盘中,各种数据结构的实现较为麻烦(如map、priority_queue…)

哈希切分

问题1:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?

问题分析:

  1. 100G的文件 -> 普通人的内存中肯定放不下,所以需要一种方式来存储
  2. 需要记录IP出现的次数

如何存储?

使用位图来存储,可能是很多人第一时间想到的方案,但是他存在几个问题:

  1. 如何记录数据的出现次数?或许你可以通过扩展位图的方式(多个bit记录一个数据,这样就可以记录数据出现的次数),但是在极端情况下(如100G的文件全是同一个IP),你不知道应该将几个bit用来记录一个数据的出现次数
  2. 假设我们有8G的内存,如果使用位图存储,假设不记录出现次数,那么假设这100G的IP都不相同,每个IP占10个字节。那么要想将他们全部存储到位图中,则位图需要开辟100G/10B=10,485,76010G的空间,此时已经不够用了(更不用说扩展位图来增加对数据的计数了)

所以我们就需要使用哈希切分的方法

解决方案:

使用哈希切分,原理:

在这里插入图片描述

如果一次性将100G的数据全部处理,那么我们的内存是放不下的,但是如果将这个文件分成了多个小文件(比如,分成100个大小为1G的文件,那么这些小文件内的数据就可以全部读入内存中)

  • 遍历这个100G的文件(因为一次只提取一个IP数据,所以不会存在内存空间不够的情况)
  • 对遍历到的每一个IP做一次哈希映射并模100,得到的数据是多少,就追加写入第几个小文件中,这样就保证相同的IP一定会进入相同的文件
  • 遍历完之后,将每个小文件中的数据放入内存中,用map或unordered_map来记录IP的出现次数,通过比较找出最大值

这里我们对100G文件在极端情况下进行说明:

  1. 如果IP值全一样,那么这100G的数据全部会映射到一个小文件中(小文件可以很大,前面只是假设为1G),那这个小文件内的所有数据也放不进内存中,岂不是和没有映射一样了吗?对,这确实和没有映射一模一样,采用map或unordered_map可以解决这种情况下数据不能全放入内存的问题
  2. 如果IP值全不一样,那么这100G的数据在进行映射+模后,会出现如下情况:
    • 哈希函数设置的合理:100G的IP映射到了各种不同的小文件中,这样每次只对一个小文件进行处理,内存空间就足够收纳所有的小文件的数据了
    • 哈希函数设置的不合理:产生了大量的冲突,导致大量的IP都进入了一个文件中,此时你可以进行一下检查:如果你的小文件中的数据大小已经超过了1G,则使用另一个哈希函数继续对这个1G的小文件进行哈希切分(即再用几个1G的文件来映射该小文件的内容)

问题2:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到top K的IP?

方法1:在前面的基础上,进行多次最大值的查找,每一次都将前一次查找最大值屏蔽掉。

方法2:使用priority_queue代替map来存储数据,控制priority_queue的大小为K,就可以实现了

位图应用

问题3:给定100亿个整数,设计算法找到只出现一次的整数?

问题分析:

  1. 100亿个整数 -> 如果使用1个bit记录一个数据,假设整数占4个字节,则一个位图需要占用2*2147483647/(8*1024*1024*1024)=0.5G的空间
  2. 只出现一次的整数 -> 则意味着需要一个计数的玩意,最次也需要一个状态位来判断出现的次数是否超过1次,所以可以采用扩展位图或者使用两个位图的方法

如何记录出现次数?

这里采用2个位图,由于一个位图需要占用0.5G的内存,所以2个位图完全够用。如果数据出现次数==1,则在位图1中的对应位置置1,第2次出现时,在位图2中对应位置置1。出现次数>2时,不对位图进行任何修改。

最后通过2个位图对应位置进行^操作,就可以判断哪些数据只出现了1次。

问题4:给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

这里我们假设整数为int占4个字节,那么总共有2*2147483647个数据。需要使用2个位图,假设一个位图的最大存储空间为0.5G,则每个文件可存储0.5*1024*1024*1024*8=4,294,967,296个数据,能覆盖整数的范围,所以1G的内存完全可以放的下两个位图

方法和前面一样,2个位图,一个记录文件1的数据,一个记录文件2的数据,最后进行一下&操作就可以实现

问题5:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

这里我们假设整数占4个字节,那么总共有2*2147483647个数据。需要使用3个位图,假设一个位图的最大存储空间为0.3G,则每个文件可存储0.3*1024*1024*1024*8=2,576,980,377个数据,此时发现不能覆盖整数的范围(该位图不能表示整数的全部数据),所以需要进行哈希切分。

在这里插入图片描述

将整数范围分成2部分,分别存入一个小文件中,共计需要2个小文件。每次将一个文件的数据通过位图存入内存中。
内存中的数据范围是(0,2147483647),0.3G的位图能存放的下,1G的内存也能存放的下3个位图。

后续方法和前面一样,此时每个区间用3个位图,如果3个位置不全为1,则说明出现次数不超过2次

布隆过滤器

问题6:给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

问题分析:

  1. 2个文件,每个文件都有100亿个query,假设每个query占50个字节,该文件大概约500G,明显1G内存存放不下,所以需要哈希切分
  2. 寻找query的交集,是否可以用位图、布隆过滤器
  3. 需要提供两种算法:近似算法(允许存在误差)和精确算法(要求查询结果准确)

近似算法:

由于允许存在误差,所以可以采用布隆过滤器,其特性就是不存在漏报,但存在误报。

1G的内存最多可以通过位图表示1*1024*1024*1024*8=8,589,934,592个数据(query)。我们不选择对他进行哈希切分(虽然只有8亿的表示范围,因为是近似算法,所以允许误差),直接使用布隆过滤器,如图:

在这里插入图片描述

  1. 选择若干个哈希函数,将每个query映射到位图上
  2. 文件1映射完后,就可以通过布隆过滤器查找文件2和文件1的交集了(会有误差)

精确算法:

这种算法的要求是不能存在误报,所以每个数据的映射必须没有冲突,那就采用哈希切分吧!

具体操作:

该文件大约500G,2个文件大约1000G

我们可以将其分成500个+500个的小文件,分别处理文件1和文件2,采用切分+模的方法存放query,使得相同的query映射进相同的文件
最后分别读取文件1和文件2的对应小文件,采用set就可以实现交集判断

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

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

相关文章

UART、SPI 与 I2C:走线和布局指南

这是翻译自PCB Hero的一篇非常基础的文章。 还有一篇关于这三个总线的比较文章可以参照阅读一下:https://www.totalphase.com/blog/2021/12/i2c-vs-spi-vs-uart-introduction-and-comparison-similarities-differences/ I2C、SPI、UART 之间的差异及其布局指南 从8位到32位的…

ECP44304T-76是一款增强型通信处理器吗?

ABB ECP44304T-76是一款增强型通信处理器,专为ABB的PLC控制系统设计。 这款通信处理器的主要功能是提供PLC与其他设备或网络之间的通信接口。它支持多种通讯协议,包括但不限于Profibus、Ethernet、Modbus等,使得PLC可以轻松集成到复杂的工业…

【最大公约数 唯一分解定理 调和级数】2862. 完全子集的最大元素和

本文涉及知识点 质数、最大公约数、菲蜀定理 组合数学汇总 唯一分解定理 调和级数 LeetCode2862. 完全子集的最大元素和 给你一个下标从 1 开始、由 n 个整数组成的数组。你需要从 nums 选择一个 完全集,其中每对元素下标的乘积都是一个 完全平方数,例…

程序员学CFA——数量分析方法(六)

数量分析方法(六) 假设检验假设检验的步骤假设检验的基本思想与步骤估计与假设检验的区别假设检验的基本思想假设检验的步骤 假设检验的相关概念原假设与备择假设检验统计量及其分布显著性水平双尾检验与单尾检验p值第一类错误与第二类错误统计显著与经济…

力扣HOT100 - 155. 最小栈

解题思路&#xff1a; 辅助栈 class MinStack {private Stack<Integer> stack;private Stack<Integer> min_stack;public MinStack() {stack new Stack<>();min_stack new Stack<>();}public void push(int val) {stack.push(val);if (min_stack.i…

SpringBoot集成jxls2实现复杂(多表格)excel导出

核心依赖 需求 导出多个表格&#xff0c;包含图片&#xff0c;类似商品标签 1.配置模板 创建一个xlsx的模板文件&#xff0c;配置如下 该模板进行遍历了两次&#xff0c;因为我想要导出的数据分为两列展示&#xff0c;左右布局&#xff0c;一个循环实现不了&#xff0c;所以采…

计算机系列之面向对象、设计模式

24、面向对象技术&#xff08;重要&#xff0c;10分左右&#xff09; 1、面向对象开发 (1)对象:由数据及其操作所构成的封装体&#xff0c;是系统中用来描述客观事务的个实体&#xff0c;是构成系统的一个基本单位。一个对象通常可以由对象名、属性和方法3个部分组成。 (2)类…

YOLOV5更换转置卷积,助力涨点!

由于转置卷积是nn库自带的,所以我们直接找到models文件夹中的yolo.py文件中的 parse_model函数,再在如下图的地方添加转置卷积模块 # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license """ YOLO-specific modules.Usage:$ python models/yolo.py --cfg yolov5s.…

ARM 交叉编译搭建SSH

一、源码下载 zlib&#xff1a;zlib-1.3.1.tar.xz openssl&#xff1a;openssl-0.9.8d.tar.gz openssh&#xff1a;openssh-4.6p1.tar.gz 二、交叉编译 1、zlib 编译参考这里 2、openssl tar -xf openssl-0.9.8d.tar.gz ./Configure --prefix/opt/ssh/openssl os/compile…

一对一WebRTC视频通话系列(五)——综合调试和功能完善

本系列博客主要记录一对一WebRTC视频通话实现过程中的一些重点&#xff0c;代码全部进行了注释&#xff0c;便于理解WebRTC整体实现。 本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习&#xff0c;梳理总结后写下文章&#xff0c;对音视频相关内容感…

猿匹配,一款使用环信实现的一个开源聊天应用含服务器

前言 之前写了一篇Android开发集成聊天环信SDK3.x简单开始&#xff0c;然后最近得空开发了一款使用环信实现的实时聊天应用&#xff0c;包含简单的服务器端&#xff0c;并开源给大家&#xff0c;有兴趣的同学可以一起搞一下&#xff0c;详细介绍看下边吧 上代码 服务器&#…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《计及全生命周期成本的公交光伏充电站储能优化配置方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

清华团队开发首个AI医院小镇模拟系统;阿里云发布通义千问 2.5:超越GPT-4能力;Mistral AI估值飙升至60亿美元

&#x1f989; AI新闻 &#x1f680; 清华团队开发首个AI医院小镇模拟系统 摘要&#xff1a;来自清华的研究团队最近开发出了一种创新的模拟系统&#xff0c;名为"Agent Hospital"&#xff0c;该系统能够完全模拟医患看病的全流程&#xff0c;其中包括分诊、挂号、…

【八十五】【算法分析与设计】单调栈的全新版本,两个循环维护左小于和右小于信息,84. 柱状图中最大的矩形,85. 最大矩形

84. 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&am…

Go的安装与配置

安装 https://go.dev/dl/ 以Windows上安装为例&#xff1a; 下一步下一步&#xff0c;记住安装位置 安装完成后 win rcmd 键入go version检查是否安装成功 配置 Go 工作区 Go 在组织项目文件方面与其他编程语言不同。 Go 是在工作区的概念下工作的。但是从版本 1.11 开始&…

docker-compose部署java项目

docker-compose是定义和运行多容器的工具。换句话说就是通过配置yml文件来运行容器&#xff0c;简化了每次输入docker run等命令&#xff0c;把这些命令配置在yml文件统一管理&#xff0c;而且可以用一个yml文件一次启动多个容器&#xff0c;启动时还可以设置各个容器的依赖关系…

远程开机与远程唤醒BIOS设置

远程开机与远程唤醒BIOS设置 在现代计算机应用中&#xff0c;远程管理和控制已成为许多企业和个人的基本需求。其中&#xff0c;远程开机和远程唤醒是两项非常实用的功能。要实现这些功能&#xff0c;通常需要在计算机的BIOS中进行一些特定的设置。以下是对远程开机和远程唤醒…

如何判断nat网络?如何内网穿透

大家都清楚&#xff0c;如果你想开车&#xff0c;就必须要给车上一个牌照&#xff0c;随着车辆越来越多&#xff0c;为了缓解拥堵&#xff0c;就需要摇号&#xff0c;随着摇号的人数越来越多&#xff0c;车牌对于想开车的人来说已经成为奢望。在如今的IPv4时代&#xff0c;我们…

全自动减压器法二氧化碳气容量测试仪:饮料行业的革新与未来

全自动减压器法二氧化碳气容量测试仪&#xff1a;饮料行业的革新与未来 一、引言 在追求品质与效率的现代饮料生产领域&#xff0c;全自动减压器法二氧化碳气容量测试仪凭借其高精度、高效率及无人工干预的显著优势&#xff0c;正逐渐成为行业的标杆。特别是在碳酸饮料的生产中…

USB系列五:USB设备配置(重要)

在USB总线接口协议中&#xff0c;对于USB外部设备功能特征是通过端点&#xff08;Endpoint&#xff09;、配置&#xff08;Configuration&#xff09;和接口&#xff08;Interface&#xff09;来描述的&#xff0c;这些就是典型的USB描述符。 USB主机通过设备请求来读取外部设…