海量数据找中位数

2023-11-12

腾讯一面问到了,用的算法导论中的Kth算法,期望时间复杂度为O(n)。后来想了想,万一数据多的来根本不能一次读入内存,这个时候该如何解决呢?

题目如下:
只有2G内存的pc机,在一个存有10G个整数的文件,从中找到中位数,写一个算法。

http://blog.sina.com.cn/s/blog_4a8aac970100093j.html~type=v5_one&label=rela_nextarticle

给出了四种方法来解决

算法:
1.利用外排序的方法,进行排序 ,然后再去找中位数
 
2.另外还有个思路利用堆
先求第1G大,然后利用该元素求第2G大,然后利用第2G大,求第3G大...当然这样的话虽不需排序,但是磁盘操作会比较多,具体还需要分析下与外排序的效率哪个的磁盘IO会比较多
建立一个1g个整数的最大值堆,如果元素小于最大值则入堆,这样可以得到第1g大的那个元素然后利用这个元素,重新建一次堆,这次入堆的条件还要加上大于这个第1g大的元素,这样建完堆可以得到第2g大的那个...
 
3.借鉴基数排序思想
偶认为可以用位来判断计数,从最高位到最低位,为了方便表述我们假设为无符号整数,即0x00000000~0xFFFFFFFF依次递增,那么可以遍历所有数据,并记录最高位为0和1的个数(最高位为0的肯定是小于最高位为1的)记为N0、N1
那么根据N0和N1的大小就可以知道中位数的最高位是0还是1
假设N0>N1,那么再计算N00和N01,
如果N00>(N01+N1),则说明中位数的最高两位是00
再计算N000和N001.。。。依次计算就能找到中位数
 
如果改进一下,设定多个计数器
好像一次磁盘io也可以统计出N0,N00,....的数值
 
4.借鉴桶排序思想
一个整数假设是32位无符号数
第一次扫描把0~2^32-1分成2^16个区间,记录每个区间的整数数目
找出中位数具体所在区间65536*i~65536*(i+1)-1
第二次扫描则可找出具体中位数数值

第一次扫描已经找出中位数具体所在区间65536*i~65536*(i+1)-1

然后第二次扫描再统计在该区间内每个数出现的次数,就可以了


http://blog.csdn.net/sytu_hzj/article/details/6856775

也有叙述

题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。

 

 

分析:既然要找中位数,很简单就是排序的想法。那么基于字节的桶排序是一个可行的方法

思想:将整形的每1byte作为一个关键字,也就是说一个整形可以拆成4个keys,而且最高位的keys越大,整数越大。如果高位keys相同,则比较次高位的keys。整个比较过程类似于字符串的字典序。

第一步:把10G整数每2G读入一次内存,然后一次遍历这536,870,912个数据。每个数据用位运算">>"取出最高8位(31-24)。这8bits(0-255)最多表示255个桶,那么可以根据8bit的值来确定丢入第几个桶。最后把每个桶写入一个磁盘文件中,同时在内存中统计每个桶内数据的数量,自然这个数量只需要255个整形空间即可。

代价:(1) 10G数据依次读入内存的IO代价(这个是无法避免的,CPU不能直接在磁盘上运算)。(2)在内存中遍历536,870,912个数据,这是一个O(n)的线性时间复杂度。(3)把255个桶写会到255个磁盘文件空间中,这个代价是额外的,也就是多付出一倍的10G数据转移的时间。

第二步:根据内存中255个桶内的数量,计算中位数在第几个桶中。很显然,2,684,354,560个数中位数是第1,342,177,280个。假设前127个桶的数据量相加,发现少于1,342,177,280,把第128个桶数据量加上,大于1,342,177,280。说明,中位数必在磁盘的第128个桶中。而且在这个桶的第1,342,177,280-N(0-127)个数位上。N(0-127)表示前127个桶的数据量之和。然后把第128个文件中的整数读入内存。(平均而言,每个文件的大小估计在10G/128=80M左右,当然也不一定,但是超过2G的可能性很小)。

代价:(1)循环计算255个桶中的数据量累加,需要O(M)的代价,其中m<255。(2)读入一个大概80M左右文件大小的IO代价。

注意,变态的情况下,这个需要读入的第128号文件仍然大于2G,那么整个读入仍然可以按照第一步分批来进行读取。

第三步:继续以内存中的整数的次高8bit进行桶排序(23-16)。过程和第一步相同,也是255个桶。

第四步:一直下去,直到最低字节(7-0bit)的桶排序结束。我相信这个时候完全可以在内存中使用一次快排就可以了。

 

 

整个过程的时间复杂度在O(n)的线性级别上(没有任何循环嵌套)。但主要时间消耗在第一步的第二次内存-磁盘数据交换上,即10G数据分255个文件写回磁盘上。一般而言,如果第二步过后,内存可以容纳下存在中位数的某一个文件的话,直接快排就可以了。关于快排的效率,可以看看我博客中的数据



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海量数据找中位数 的相关文章

随机推荐

  • 订单、支付、退款、发货、退货等编号自动生成类

    在商城网站中 订单编号的自动生成 ERP中各个单据的编号自动生成 都可以按照一下的方式来自动生成 第一步 定义常量订单编号前缀 订单编号起始数 订单编号步长 public static final String ORDER SN PREFI
  • 固定资产批导程序

    Responsibility Program Name ZFIC001 Date written Author s name SongQiong Last update Program title 固定资产期初批量导入程序 Project
  • 【基础知识】5、相机内外参矩阵和坐标变换

    文章目录 1 世界坐标系和相机坐标系的关系 从世界坐标系到相机坐标系 涉及到物体的旋转和平移 绕着不同的坐标轴旋转不同的角度 得到相应的旋转矩阵 如下图所示 于是 从世界坐标系到相机坐标系 涉及到旋转和平移 其实所有的运动也可以用旋转矩阵和
  • npcap关闭_npcap是什么软件

    npcap是一个网络数据包抓包工具 是WinPcap的改进版 它支持NDIS 6技术 只允许管理员Administrator 访问Npcap 与WinPcap兼容或并存两种模式 支持Windows平台的回环数据包采集和发送 本教程操作环境
  • 性能测试_JMeter中你可能会忽略的细节点-2

    目录 CSV参数化有什么缺陷 在哪里可以体验到 JDBC请求报错Variable Name must not be null in JDBC Request 助攻机tar包和zip包要注意的事项 文件夹的执行权限 JMeter分布式主机假死
  • ACLR指标

    文章目录 一 ACLR含义 二 ACLR来源 一 ACLR含义 ACLR Adjacent Channel Leakage Power Ratio 测试目的 避免对邻近信道产生干扰 LTE和ACLR测试除了需要测试自身带宽相同的邻信道泄漏功
  • okGo详细使用步骤(一)

    OkGo的使用 一 详细使用方式可以直接观看源文档wiki 这里不再说明 本文档也是依赖于源文档进行代码测试和理解写的 写此文档时okgo版本 compile com lzy net okgo 3 0 4 几个库的介绍 library名 简
  • basler相机pylon安装及API调用

    1 官网下载basler相机的pylon 2 安装pylon 2 1选择pylon的模式 二次开发选择development模式 2 2选择接口 看相机的接口类型 选择相机的接口类型一般为GitE和USB类型 3 完后安装就打开Pylon
  • AUBO机械臂常用函数和指令详解(C/C#版本)

    我是厂妹 扩充一下上一篇内容 C 引用的C生成的DLL 所以直接一起介绍 部分不同会写出来 目录 头文件和引用部分 初始化和主要参数 根据基础坐标系运动操作 机械臂轴动 运动函数 设置基于基座系运动偏移量 获取机械臂当前位置信息 获取机械臂
  • FlowJo 10.4.0(流式细胞分析器工具)

    FlowJo mac是一款流式细胞仪数据分析软件 广泛用于生物医学研究领域 它提供了强大的功能和直观的用户界面 使用户能够对流式细胞仪收集的数据进行高级分析和可视化 FlowJo for mac具有以下主要特点 数据导入和预处理 FlowJ
  • oracle连接mysql详解linux_Linux平台Oracle连接MySQL

    前言 Windows平台Oracle连接MySQL的方法已经给大家介绍过了 现在大部分的Oracle和MySQL都是在Linux平台上面 刚好最近也有这种需求 顺手把整个搭建过程记录起来和大家分享 原理 通过ODBC连接MySQL的原理图
  • LU分解(LU Factorization)计算方法(手算+MATLAB),关于置换矩阵(Permutation Matrix),部分主元消去法(Partial Pivoting)

    背景 求解一些列具有相同系数矩阵的线性方程 如 A x b 1 Ax b 1 Ax b1
  • Python爬虫之Jsonpath解析

    Jsonpath的安装方式 pip install jsonpath i https pypi douban com simple 利用国内源速度快一些 jsonpath的使用 针对json数据结构进行数据解析 本地文件 服务器文件需要先下
  • 2023年黑客零基础从入门到精通学习成长路线(超多图、非常详细),看完这一篇就够了。

    怎样规划学习路线 如果你是一个安全行业新人 我建议你先从网络安全或者Web安全 渗透测试这两个方向先学起 一是市场需求量高 二则是发展相对成熟入门比较容易 值得一提的是 学网络安全 是先网络后安全 学Web安全 也是先Web再有安全 安全不
  • mysql 存储过程参考 虽然不建议用存储过程,一个例子 用于自己参考

    BEGIN DECLARE done INT DECLARE v companyName VARCHAR 100 DECLARE v phone VARCHAR 30 DECLARE v contactName VARCHAR 30 DEC
  • 论文笔记:On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima

    2017 ICLR 0 摘要 这篇文章探究了深度学习中一个普遍存在的问题 使用大的batchsize训练网络会导致网络的泛化性能下降 Generalization Gap 大的batchsize训练使得目标函数倾向于收敛到sharp min
  • ubuntu18.04 安装OpenBLAS

    一 通过apt get安装 sudo apt get install libopenblas dev 二 源码安装 下载OpenBLAS并安装 git clone https github com xianyi OpenBLAS git c
  • [人工智能-深度学习-37]:卷积神经网络CNN - 重构神经网络的疑惑与思考?

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 人工智能 深度学习 37 卷积神经网络CNN 重构神经网络的疑惑与思考 文火冰糖 王文兵 的博客 CSDN博客 如果你看懂我的疑惑 如果你能
  • MYSQL的server层和存储引擎层分析

    转自 微点阅读 https www weidianyuedu com SQL的全称是Structured Query Language 翻译成中国话就是结构化查询语言 这是一种声明式的语法 何为声明式 对于设计数据库的人而言 语句怎么执行就
  • 海量数据找中位数

    腾讯一面问到了 用的算法导论中的Kth算法 期望时间复杂度为O n 后来想了想 万一数据多的来根本不能一次读入内存 这个时候该如何解决呢 题目如下 只有2G内存的pc机 在一个存有10G个整数的文件 从中找到中位数 写一个算法 http b