『 C++ 』海量数据处理

文章目录

    • 🦖 快速找出海量数据中是否存在该整型数据
    • 🦖 有限内存情况下两个文件(海量query)中找出交集
    • 🦖 海量数据中找出只出现1次的数据
    • 🦖 有限内存情况下两个文件(整型)找出交集
    • 🦖 海量数据中找出出现次数不超过2次的数据
    • 🦖 海量数据中找出topK的IP

请添加图片描述


🦖 快速找出海量数据中是否存在该整型数据

请添加图片描述

在上篇文章『 C++ - STL 』位图(BitMap)与布隆过滤器(Bloom Filter)-CSDN博客中提到一题关于腾讯的面试题;

  • 存在40亿个不重复的无符号整数,且无符号整数没排过序,给定一个无符号整数,如何快速判断一个数是否存在40亿数据当中;

这种题型为判断一个数据是否存在的问题,在C++STL当中首先可以考虑set,unordered_set用于判断数据是否存在;

但是这题出现了另一个关键字 40亿 ;

  • 这意味着数据不能直接存储至内存当中

    40亿个无符号整型在32位的机器下大小约为16GB;

    在一般的机器下无法能够完全将该数据量的数据存储至内存当中;

当然也可以使用以下思路:

  • 排序+二分查找

    先对数据进行排序,再使用二分查找的思路对数据进行甄别;

    排序的时间复杂度最理想的情况其时间复杂度为O(NlogN);

    二分查找的时间复杂度为logN;

  • 逐个数据进行遍历

    使用逐个数据进行遍历的方式时间复杂度为O(N);

尽管上述方式都能使其在40亿个数据中判断该数据是否存在,但整体效率过低;

在这种情况下即可以使用在『 C++ - STL 』位图(BitMap)与布隆过滤器(Bloom Filter)-CSDN博客 文章中所使用的位图;

以其使用位运算的方式将原数据大小为16GB缩减至512MB,且使用位图的时间复杂度基本上为常数级别O(1);


🦖 有限内存情况下两个文件(海量query)中找出交集

请添加图片描述

  • 存在两个文件,分别有100亿个query,我们只有1GB内存,如何找到两个文件交集?

    假设1个query的大小为50byte,一个文件100亿个query的大小则为 5000亿byte;

    5000亿byte换算大小大约为500GB;

在这种情况下可以使用 分割 的方式将文件 分割 为若干个小文件;

以当前情况为例,该题中限制内存大小为1GB,则可以将文件 分割 为若干个约500MB大小的小文件;

再将各个小文件放置于内存当中的set或者unordered_set容器当中判断其交集;

但是若是将文件进行平均切分,在遍历时只能采用暴力枚举的方式,对于检查的效率将会低至 O(N2) ,即每个文件都需要遍历另一组的所有小文件从而找出其中的交集;

  • 而在这种情况为了避免该情况发生可以使用类似哈希桶的方式使大文件分割成小文件

    遍历每个大文件,并使用一个哈希函数将文件中的各个query进行区分至各个小文件内;

    如: i = HashFunc(query) % 1000

在使用该方式之后只需要将Ai文件与Bi文件放置不同的setunordered_set并寻找交集即可;

在使用该方法对两个大文件进行处理的优势是,由于使用了哈希函数所以具有冲突或者完全相同的query将会放置在对应下标的小文件当中,从而可以使得进行比较寻找交集,一般这种方式被称作 哈希切割 ;

但是使用这种方式也会出现对应的问题:

  • 将数据放置在setunordered_set当中可能会出现 抛异常 bad_alloc

    这是因为采用 哈希切割 的切割方式,该方式并不是使得文件像上文所述的 平均切 方式从而导致了单个文件过大而不能完全加载进内存当中;

    以该图为例(A1文件与B1文件过大);

在这种文件过大的情况下通常有两种情况:

  • 文件内存在大量不同且冲突的query;
  • 文件中存在大量相同的query;

若是出现文件内存在大量不相同且出现哈希冲突的query时则换另一个哈希函数对该小文件重新进行 哈希切割 再次分成若干个小文件即可即可;

而文件中存在大量相同的query时,由于set或者unordered_set容器具有去重的功能,所以在一般情况下文件中存在大量相同query的情况时并不会抛出内存异常,只需要插入至对应的set或者unordered_set容器即可;

  • 那么如何控制使得可以灵活进行 哈希切割 或是载入内存?

    set容器与unordered_set容器在插入数据时,将会出现三种情况:

    • 插入成功

      当数据插入成功时将会返回pair,其中pair内存在对应的迭代器以及true;

    • 插入失败

      当数据存在时将会返回pair,其中pair内存在对应的迭代器以及false;

    • 插入失败(抛异常)

      当内存不够时程序将抛出异常bad_alloc;

    只需要灵活对异常进行处理则可以实现灵活进行 哈希切割 或是载入内存进行后续操作;


🦖 海量数据中找出只出现1次的数据

请添加图片描述

  • 存在100亿个整数,找出只出现一次的整数;

该题为找出只出现一次的数据;

那么该思路可以使用 位图 进行解答;

因为数据量为100亿,而整型的最大值为 232-1,故数据中必然存在大量的重复数值,而位图当中可以精确计算数据对应的是否存在问题,其最大数据为 232-1 ;

而位图中由于数据的存在表示为二进制01进行表示,故在此处只使用一个位图并不能很好的解决该问题;

而若是使用两个位图进行映射则可以表示4种情况,分别为00,01,10,11;

class bits{public:void set(const int n);void reset(const int n);private:std::bitset<-1> _bits1;std::bitset<-1> _bits2;
};

根据数据的情况以此对两个位图分别进行set操作即可;

在该题中可以将数据分为以下情况:

  • 数据不存在

    当数据不存在时不需要进行set操作,其对应映射为00;

  • 数据存在一个

    当数据对应的映射为00时遍历到该数据时将其对应映射位置set01,表示该数据出现一次;

  • 数据存在两个及以上

    当数据对应的映射为01时再次遍历到相同数据将其对应映射位置set10,表示数据出现过不止一次;

    当数据持续出现时且当前对应数据映射为10时保持不变(由于只需要判断只出现过 1次 的数据,不需要其他冗余操作);

最后检查位图对应的映射即可找出只出现一次的数据;


🦖 有限内存情况下两个文件(整型)找出交集

请添加图片描述

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

该题与上文中 有限内存情况下两个文件(海量query)中找出交集 题目类似,即在有限内存当中找出两个文件海量数据中的交集;

唯一不同的是该题的数据类型为整型;

由于整型的最大值为 232-1,而给定的文件的数据数据量分别有100亿个,故两个文件中都必然存在大量的重复数值;

在这种情况中只需要使用位图即可以解决:

  • 使用两个位图

    定义两个位图,两个位图都对应着其中一个文件;

    位图可进行映射与去重的操作,可将两个文件遍历并映射至位图当中进行去重;

    最终比较两个位图找出其中对应的交集;

  • 使用一个位图

    定义一个位图,该位图对应两个文件中的其中一个文件;

    遍历一个文件将该文件中的所有数据映射至位图当中;

    再次遍历另外一个文件,当遇到相同值时保存该值(该数据为交集),并将该数据对应的映射置为0,即reset操作;

两种方式对应的都有它的优缺点;

若是不需要频繁找其交集时可采用 方法2 寻找交集;

而若是需要频繁找数据的交集时则可以采用 方法1 从而降低每次访问文件的时间;


🦖 海量数据中找出出现次数不超过2次的数据

请添加图片描述

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

该题与上文中 海量数据中找出只出现1次的数据 题目类似,且可以使用相同的模型进行解答;

由于在 海量数据中找出只出现1次的数据 题中所采用的模型为2个位图进行实现,其可以控制00,01,10,11四种情况;

在该题中且只需要该几种情况即可;

  • 数据不存在

    当该数据不存在时其对应两个位图的映射为00;

  • 数据出现1次

    当该数据对应的映射为00,且遍历至该数据时,将该数据置为01,表示数据出现1次;

  • 数据出现2次

    当该数据对应的映射为01,且遍历至该数据时,将该数据置为10,表示数据出现2次;

  • 数据出现3次及以上

    当该数据对应的映射为10,且遍历至该数据时,将该数据置为11,表示数据出现3次;

    当数据对应映射位置为11,且遍历至该数据时不采取措施,表示该数据出现3次或3次以上;


🦖 海量数据中找出topK的IP

请添加图片描述

  • 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?与上题条件相同,如何找到top K的IP?

该题的解法与上文中 有限内存情况下两个文件(海量query)中找出交集 中的解决方式类似;

由于文件过大且类型为字符串类型,故不能采用位图进行操作;

再处理该题时则可以使用上文中出现的 哈希切割 的方式将大文件分成若干个小文件;

使用哈希函数遍历大文件中的IP,并对其使用哈希函数并放置在对应的小文件当中;

将切分后的小文件采用map或者unordered_map统计其出现次数(相同或者冲突的IP将会存放至同一个文件内);

在遍历小文件的过程当中可能会出现抛内存异常bad_alloc;

当出现抛该异常时说明在遍历小文件的过程中某个文件中的数据量过大;

此时说明该小文件中冲突的数据(IP)过多,导致的无法将小文件完全读取至内存当中;

此时只需要换一个哈希函数再次对该小文件进行 哈希切割 成更小的文件进行遍历即可;

并对其使用哈希函数并放置在对应的小文件当中;

将切分后的小文件采用map或者unordered_map统计其出现次数(相同或者冲突的IP将会存放至同一个文件内);

在遍历小文件的过程当中可能会出现抛内存异常bad_alloc;

当出现抛该异常时说明在遍历小文件的过程中某个文件中的数据量过大;

此时说明该小文件中冲突的数据(IP)过多,导致的无法将小文件完全读取至内存当中;

此时只需要换一个哈希函数再次对该小文件进行 哈希切割 成更小的文件进行遍历即可;

而对于题目当中的对于Top K问题则可以建一个小堆Heap从而实现Top K的问题;

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

挑战杯 YOLOv7 目标检测网络解读

文章目录 0 前言1 yolov7的整体结构2 关键点 - backbone关键点 - head3 训练4 使用效果5 最后 0 前言 世界变化太快&#xff0c;YOLOv6还没用熟YOLOv7就来了&#xff0c;如果有同学的毕设项目想用上最新的技术&#xff0c;不妨看看学长的这篇文章&#xff0c;学长带大家简单的…

5G——小区搜索流程

小区搜索流程 小区搜索目标&#xff1a;读取到SIB1. 小区搜索流程概述&#xff1a;SIB1在PDSCH信道承载&#xff0c;承载SIB1的信道在哪个位置由PDCCH告诉&#xff0c;而PDCCH的基本信息由MIB告诉&#xff0c;MIB信息由广播信道PBCH广播出去&#xff0c;物理信道解调需要解调…

vue3-组合式 API

什么是组合式 API&#xff1f; 组合式 API (Composition API) 是一系列 API 的集合&#xff0c;使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语&#xff0c;涵盖了以下方面的 API&#xff1a; 响应式 API&#xff1a;例如 ref() 和 reactive()&a…

HttpRunner自动化测试之实现参数化传递

参数化实现及重复执行 参数化测试&#xff1a;在接口测试中&#xff0c;为了实现不同组数据对同一个功能模块进行测试&#xff0c;需要准备多组测试数据对模块进行测试的过程。 在httprunner中可以通过如下方式实现参数化&#xff1a; 1、在YAML/JSON 中直接指定参数列表 2、…

【C++】C++入门

关于C是什么 C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff0c;20世纪80年代&#xff0c;计算机界提出了OOP(object or…

静态时序分析:SDC约束命令set_clock_latency详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 时钟的延迟可以使用set_clock_latency命令设置&#xff0c;这里的时钟延迟包括源延迟(source latency)&#xff0c;即时钟对象到时钟源对象&#xff08;时钟定义…

Linux——网络通信TCP通信常用的接口和tcp服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符&#xff0c;他的作用就是打开一个网络通讯端口&#xff0c;返回的这个描述符其实就可以理解为一个文件描述符&a…

抖音关键词搜索爬虫,抖音API数据接口,抖音商品详情数据采集

抖音商品API接口抖音关键词搜索抖音直播间小黄车抖店商品数据采集 除了微博&#xff0c;小红书&#xff0c;抖音也是一个巨大的流量池。 除了评论&#xff0c;其实关键词搜索视频是更为常见的一个需求&#xff0c;于是上周末抽空开发了下&#xff0c;完成了 mvp。

数据结构——lesson3单链表介绍及实现

目录 1.什么是链表&#xff1f; 2.链表的分类 &#xff08;1&#xff09;无头单向非循环链表&#xff1a; &#xff08;2&#xff09;带头双向循环链表&#xff1a; 3.单链表的实现 &#xff08;1&#xff09;单链表的定义 &#xff08;2&#xff09;动态创建节点 &#…

【数据结构】链表OJ面试题5《链表的深度拷贝》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 给定一个链表&#xff0c;判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 给定一个链表&#xff0c;返回链表开始入环的第一个结点。 如果链表无环&#xff0c;则返回 NULLhttp://t.cs…

OpenCV识别人脸案例实战

使用级联函数 基本流程 函数介绍 在OpenCV中&#xff0c;人脸检测使用的是cv2.CascadeClassifier.detectMultiScale()函数&#xff0c;它可以检测出图片中所有的人脸。该函数由分类器对象调用&#xff0c;其语法格式为&#xff1a; objects cv2.CascadeClassifier.detectMul…

vue-进阶语法(四)

目录 v-model原理 v-model应用于组件 sync修饰符 ref 和 $refs&#xff08;重点&#xff09; $nextTick v-model原理 原理&#xff1a;v-model本质上是一个语法糖。例如应用在输入框上&#xff0c;就是 value属性 和 input事件 的合写。 作用&#xff1a;提供数据的双向…

[NSSRound#16 Basic]Web

1.RCE但是没有完全RCE 显示md5强比较&#xff0c;然后md5_3随便传 md5_1M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&md5_2M%C9h%FF%0E%E3%5C%20%95r%D4w…

ClickHouse--08--SQL DDL 操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 SQL DDL 操作1 创建库2 查看数据库3 删除库4 创建表5 查看表6 查看表的定义7 查看表的字段8 删除表9 修改表9.1 添加列9.2 删除列9.3 清空列9.4 给列修改注释9.5 修…

大数据01-导论

零、文章目录 大数据01-导论 1、数据与数据分析 **数据&#xff1a;是事实或观察的结果&#xff0c;是对客观事物的逻辑归纳&#xff0c;是用于表示客观事物的未经加工的原始素材。**数据可以是连续的值&#xff0c;比如声音、图像&#xff0c;称为模拟数据&#xff1b;也可…

【网络安全】什么样的人适合学?该怎么学?

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a; 什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 当然&#xff0c;产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级…

Web 扫描神器:WhatWeb 保姆级教程(附链接)

一、介绍 WhatWeb 是一款用于识别网站技术栈和特征的开源Web扫描工具。它可以自动分析网站的响应并识别出使用的Web框架、CMS、服务器、JavaScript库等技术组件。WhatWeb的目标是通过分析网站的内容&#xff0c;提供有关目标的技术信息&#xff0c;这对于安全测试、漏洞评估和…

Jetpack Compose 第 2 课:布局

点击查看&#xff1a;Jetpack Compose 教程 点击查看&#xff1a;Composetutorial 代码 简介 Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API&#xff0c;可以帮助您简化并加快 Android 界面开发。 在本教程中&a…

Quartz---基础

1.概述 Quartz是一个完全由Java编写的开源任务调度框架&#xff0c;通过触发器来设置作业定时运行规则&#xff0c;控制作业的运行时间。Quartz框架的主要核心组件包括调度器、触发器和作业。调度器作为作业的总指挥&#xff0c;触发器作为作业的操作者&#xff0c;而作业则为应…

前端常见的设计模式

说到设计模式&#xff0c;大家想到的就是六大原则&#xff0c;23种模式。这么多模式&#xff0c;并非都要记住&#xff0c;但作为前端开发&#xff0c;对于前端出现率高的设计模式还是有必要了解并掌握的&#xff0c;浅浅掌握9种模式后&#xff0c;整理了这份文章。 六大原则&…