大数据量整数排序

java对大数据量文件内容的多线程读取和排序.pdf 立即下载
 题目大意:移动公司需要对已经发放的所有139段的号码进行统计排序,已经发放的139号码段的文件都存放在一个文本文件中(原题是放在两个文件中),一个号码一行,现在需要将文件里的所有号码进行排序,并写入到一个新的文件中;号码可能会有很多,最多可能有一亿个不同的号码(所有的139段号码),存入文本文件中大概要占1.2G的空间;jvm最大的内存在300以内,程序要考虑程序的可执行性及效率;只能使用Java标准库,不得使用第三方工具。 
    这是个典型的大数据量的排序算法问题,首先要考虑空间问题,一下把1.2G的数据读入内存是不太可能的,就算把1一亿条数据,转都转换成int类型存储也要占接近400M的空间。当时做个题目我并没有想太多的执行效率问题,主要就考虑了空间,而且习惯性的想到合并排序,基本思想是原文件分割成若干个小文件并排序,再将排序好的小文件合并得到最后结果,算法大概如下: 

    1.顺序读取存放号码文件的中所有号码,并取139之后的八位转换为int类型;每读取号码数满一百万个(这个数据可配置)将已经读取的号码排序并存入新建的临时文件。 
    2.将所有生成的号码有序的临时文件合并存入结果文件。
 

    这个算法虽然解决了空间问题,但是运行效率极低,由于IO读写操作太多,加上步骤1中的排序的算法(快速排序)本来效率就不高(对于电话排序这种特殊情况来说),导致1亿条数据排序运行3个小时才有结果。 

    如果和能够减少排序的时间呢?首当其冲的减少IO操作,另外如果能够有更加好排序算法也行。前天无聊再看这个题目时突然想到大三时看《编程珠玑》时上面也有个问题的需求这个这个题目差不多,记得好像使用是位向量(实际上就是一个bit数组),用电话作为index,心中大喜,找到了解决此问题的最完美方案啦:用位向量存储电话号码,一个号码占一个bit,一亿个电话号码也只需要大概12M的空间;算法大概如下: 
      1.初始化bits[capacity]; 
      2.顺序所有读入电话号码,并转换为int类型,修改位向量值:bits[phoneNum]=1; 
      3.遍历bits数组,如果bits[index]=1,转换index为电话号码输出。
 
    Java中没有bit类型,一个boolean值占空间为1byte(感兴趣的可以自己写程序验证),我自己写个个用int模拟bit数组的类,代码如下: 
   
Java代码  收藏代码
  1. public class BitArray {  
  2.     private int[] bits = null;  
  3.     private int length;  
  4.     //用于设置或者提取int类型的数据的某一位(bit)的值时使用  
  5.     private final static int[] bitValue = {  
  6.         0x80000000,//10000000 00000000 00000000 00000000        
  7.         0x40000000,//01000000 00000000 00000000 00000000        
  8.         0x20000000,//00100000 00000000 00000000 00000000        
  9.         0x10000000,//00010000 00000000 00000000 00000000        
  10.         0x08000000,//00001000 00000000 00000000 00000000        
  11.         0x04000000,//00000100 00000000 00000000 00000000        
  12.         0x02000000,//00000010 00000000 00000000 00000000        
  13.         0x01000000,//00000001 00000000 00000000 00000000        
  14.         0x00800000,//00000000 10000000 00000000 00000000        
  15.         0x00400000,//00000000 01000000 00000000 00000000        
  16.         0x00200000,//00000000 00100000 00000000 00000000        
  17.         0x00100000,//00000000 00010000 00000000 00000000        
  18.         0x00080000,//00000000 00001000 00000000 00000000        
  19.         0x00040000,//00000000 00000100 00000000 00000000        
  20.         0x00020000,//00000000 00000010 00000000 00000000        
  21.         0x00010000,//00000000 00000001 00000000 00000000            
  22.         0x00008000,//00000000 00000000 10000000 00000000        
  23.         0x00004000,//00000000 00000000 01000000 00000000        
  24.         0x00002000,//00000000 00000000 00100000 00000000        
  25.         0x00001000,//00000000 00000000 00010000 00000000        
  26.         0x00000800,//00000000 00000000 00001000 00000000        
  27.         0x00000400,//00000000 00000000 00000100 00000000        
  28.         0x00000200,//00000000 00000000 00000010 00000000        
  29.         0x00000100,//00000000 00000000 00000001 00000000        
  30.         0x00000080,//00000000 00000000 00000000 10000000        
  31.         0x00000040,//00000000 00000000 00000000 01000000        
  32.         0x00000020,//00000000 00000000 00000000 00100000        
  33.         0x00000010,//00000000 00000000 00000000 00010000        
  34.         0x00000008,//00000000 00000000 00000000 00001000        
  35.         0x00000004,//00000000 00000000 00000000 00000100        
  36.         0x00000002,//00000000 00000000 00000000 00000010        
  37.         0x00000001 //00000000 00000000 00000000 00000001              
  38.     };  
  39.     public BitArray(int length) {  
  40.         if(length < 0){  
  41.             throw new IllegalArgumentException("length必须大于零!");  
  42.         }  
  43.         bits = new int[length / 32 + (length % 32 > 0 ? 1 : 0)];  
  44.         this.length = length;  
  45.     }  
  46.     //取index位的值  
  47.     public int getBit(int index){  
  48.         if(index <0 || index > length){  
  49.             throw new IllegalArgumentException("length必须大于零小于" + length);  
  50.         }  
  51.         int intData = bits[index/32];  
  52.         return (intData & bitValue[index%32]) >>> (32 - index%32 -1);  
  53.     }  
  54.     //设置index位的值,只能为0或者1  
  55.     public void setBit(int index,int value){  
  56.         if(index <0 || index > length){  
  57.             throw new IllegalArgumentException("length必须大于零小于" + length);  
  58.         }         
  59.         if(value!=1&&value!=0){  
  60.             throw new IllegalArgumentException("value必须为0或者1");  
  61.         }  
  62.         int intData = bits[index/32];  
  63.         if(value == 1){  
  64.             bits[index/32] = intData | bitValue[index%32];  
  65.         }else{  
  66.             bits[index/32] = intData & ~bitValue[index%32];  
  67.         }  
  68.     }  
  69.     public int getLength(){  
  70.         return length;  
  71.     }     
  72. }      
  73.       

    
    bit数组有了,剩下就是算法代码,核心代码如下: 
   
Java代码  收藏代码
  1. bitArray = new BitArray(100000000);   
  2. //顺序读取所有的手机号码  
  3. while((phoneNum = bufferedReader.readLine())!=null){  
  4.     phoneNum = phoneNum.trim().substring(3);//13573228432  
  5.     //取139后8位转换为int类型  
  6.     phoneNumAsInt = Integer.valueOf(phoneNum);  
  7.     //设置对应bit值为1  
  8.     bitArray.setBit(phoneNumAsInt, 1);  
  9. }     
  10. //遍历bit数组输出所有存在的号码  
  11. for(int i = 0;i<sortUnit;i++){  
  12.     if(bitArray.getBit(i)==1){  
  13.             writer.write("139" + leftPad(String.valueOf(i + sortUnit*times), 8));  
  14.             writer.newLine();                         
  15.     }                 
  16. }  
  17. writer.flush();  
  18.    

    经测试,修改后的算法排序时只需要20多M的内存,一亿条电话号码排序只要10分钟(时间主要花在IO上),看来效果还是很明显的。 
    这个算法很快,不过也有他的局限性: 
    1.只能用于整数的排序,或者可以准确映射到正整数(对象不同对应的正整数也不相同)的数据的排序。 
    2.不能处理重复的数据,重复的数据排序后只有一条(如果有这种需求可以在这个算法的基础上修改,给出现次数大于1的数据添加个计数器,然后存入Map中) 
    3.对于数据量极其大的数据处理可能还是比较占用空间,这种情况可配合多通道排序算法解决。 

    PS:这个算法的思想源于《编程珠玑》,有兴趣的可以读读那本书,非常不错!
光电式烟雾传感器实战指南(一) 光迷宫设计与散射原理篇 本文深入解析了光电式烟雾传感器的核心部件——光迷宫的设计原理与光散射机制。文章详细阐述了如何通过精心设计的光学结构实现‘透气不透光’,并重点探讨了前向散射(尤其是135°角)在提升烟雾监测系统灵敏度与可靠性中的关键作用,为DIY爱好者提供了从理论到实践的完整指南。 阅读详情

相关推荐

0/1背包问题:从暴力递归到动态规划详解

题目: 有一组数量为 n 个物品,每个物品都有重量w 和价值v 给定一个背包bag,背包装的物品不能超过背包最大载重容量返回背包bag 能装下的最大价值1. 物品的重量和价值:2. 背包的容量:暴力解法的核心是递归,通过逐一决策每个物品是否放入背包,最终找到最优解。状态定义:递归逻辑:递归终止条件: 动态规划解法 递归的暴力解法有重复子问题,导致了大量的重复计算。为了解决这个问题,我们可以使用动态规划来优化。状态定义:状态转移:边界条件: 测试方法 示例解析 假设:我们希望找到在容量为

Mr.Ayao's blog 2065

java 大数据量排序算法

Java 有很多算法可以用来排序大数据量的数据。其中一些常见的算法包括: 快速排序 (QuickSort):这是一种分治算法,它的时间复杂度为 O(nlogn),通常是很快的。 归并排序 (MergeSort):这也是一种分治算法,它的时间复杂度为 O(nlogn)。 堆排序 (HeapSort):这是一种选择排序算法,它的时间复杂度为 O(nlogn)。 这三种算法都是基于比较的排序算...

weixin_42576804的博客 573

STM32H723ZGT6-单ADC极限采样率实战与分辨率权衡

本文通过实战测试,深入探讨了STM32H723ZGT6微控制器中单ADC模块的极限性能。文章详细展示了如何通过CubeMX配置时钟树、ADC参数、定时器触发与DMA,实测得出在16位分辨率下最高稳定采样率约为4.6MHz,而将分辨率降至8位后,采样率可提升至约6.2MHz,并分析了速度与分辨率之间的关键权衡,为高速数据采集项目提供选型与优化参考。

weixin_29240711的博客 297

公司的一道考试题算法分析——大数据量整数排序

题目大意:移动公司需要对已经发放的所有139段的号码进行统计排序,已经发放的139号码段的文件都存放在一个文本文件中(原题是放在两个文件中),一个号码一行,现在需要将文件里的所有号码进行排序,并写入到一个新的文件中;号码可能会有很多,最多可能有一亿个不同的号码(所有的139段号码),存入文本文件中大概要占1.2G的空间;jvm最大的内存在300以内,程序要考虑程序的可执行性及效率;只能使用Java...

v5browser 342

UE4_UE5 自定义简单水材质(UE材质图表大全1)

首先是材质的颜色节点、粗糙度节点、透明度节点。(1/2/3/4键+右键空白处,可创建一/二/三/四维节点)接着是两个法线波动节点的叠加。最后是折射节点,将fresnel菲涅尔节点连接到材质结果节点的折射输入端。到这里,你基本已经实现了一个波纹流动的水材质。后续我会更新加上海面浪花的水面材质,可以到我的专栏中寻找。有问题随时私信沟通,加油❤。

shanlinhan的博客 1985

单相全桥逆变三种SPWM调制方式(单极/双极/倍频)到底怎么选?一篇讲透优缺点与选型

本文深入解析单相全桥逆变器中单极性、双极性和单极性倍频三种SPWM调制方式的原理与工程选型策略。通过对比开关损耗、谐波特性和驱动复杂度等关键指标,提供基于STM32的实战方案和选型框架,帮助工程师在新能源发电、电机驱动等应用中做出最优决策。

weixin_34046298的博客 803

数据量很大的排序问题 大量数据如何排序

数据量很大的排序问题 大量数据如何排序     【尊重原创,转载请注明出处】http://blog.youkuaiyun.com/guyuealian/article/details/51119499     同学某天参加腾讯面试,技术面的时候,面试官问了排序问题:     问题一:若有1T的数据,需要实现由大到小排序,你用什么办法,说说你的思路和想法?     问题二:有10个G的数据,如果

AI吃大瓜的博客 3万+

解决银河麒麟V10分辨率问题:xrandr命令详解与常见错误排查

本文详细解析了在银河麒麟V10系统中使用xrandr命令调整屏幕分辨率的方法,包括核心功能解析、常见问题排查及持久化配置技巧。通过实战指南帮助用户解决分辨率缺失、配置失效等典型问题,提升多显示器环境下的工作效率。

weixin_30642561的博客 504

大数据排序算法

一、快速排序(用的比较多) (1) 递归对所有数据分成[a,b)b(b,d]两个区间,(b,d]区间内的数都是大于[a,b)区间内的数 (2) 对(b,d]重复(1)操作,直到最右边的区间个数小于1000个。注意[a,b)区间不用划分 (3) 返回上一个区间,并返回此区间的数字数目。接着方法仍然是对上一区间的左边进行划分,分为[a2,b2)b2(b2,d2]两个区间,取(b2,d2]区间。如果...

猪大肠的世界 3439

多体动力学分析软件:SIMPACK_(3).SIMPACK模型创建与编辑

在 SIMPACK 中,模型的创建与编辑是多体动力学分析的基础。通过了解模型的基本结构、创建方法、编辑技巧和高级功能,用户可以高效地构建和优化复杂的多体系统模型。无论是手动创建、通过脚本创建还是导入现有的 CAD 模型,SIMPACK 都提供了强大的工具和灵活的接口,帮助用户实现精确和高效的仿真分析。希望本节内容对您在 SIMPACK 中进行多体系统建模有所帮助。如有任何问题或需要进一步的指导,请参考 SIMPACK 的官方文档或联系技术支持。

kkchenjj的博客 1011

DPABISurf使用教材

严老师的官方教程:http://rfmri.org/Course DPABISurf版本:dpabi50docker.tar.gz MATLAB版本:2018b 一、数据准备 (1)如果是数据的DICOM格式,整理成以下格式(注意文件夹的命名方式): 如果觉得不是很清楚,可以在官网下载Demo数据(http://rfmri.org/DemoData),参照里面的文件格式进行整理即可。 (2)如果数据是nii格式,整理成以下格式: 这里没有使用官网的demo数据进行学习,而是..

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 8519

大数据量的排序算法 -最小堆排序算法

  今天有人推荐了一个排序算法:最小堆排序算法。号称能处理10亿数据的排序问题.   正好将要面临2.5亿数据的查询计算比对问题,从没面对过如此大的数据量,之前处理过最大的表不过3000万,心里正有些惴惴不安。正好把这个算法拿来学习揣摩一番。   刚开始随手写了个递归排序,本以为想法是比对一下2种算法的,后来发现结果大跌眼镜。   下表中,表头是随机数量,内容单位为毫秒。 ...

weixin_34290000的博客 387

番外篇 | 关于YOLO11算法的改进点总结

关于YOLO11算法的改进点总结。🌈

小哥谈 2311

已知一个length为1000000的整数数组,,数组最大元素为1000,最小元素100,排序输出所有元素。

<br />已知一个length为1000000的整数数组,,数组最大元素为1000,最小元素100,排序输出所有元素。<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> 

529

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

给定整数数组,需找出其中最小的 k 个元素。核心需求是高效处理大数据量,因此需避免全排序(O(n log n)),优先选择基于堆或快排思想的 O(n log k) 解法

外部排序:当数据量超过内存时,将数据分块排序后,用大顶堆合并多个有序块(如数据库查询结果排序)。 合并k个有序链表:从每个链表头取元素入堆,堆顶为当前最小值,依次构建合并链表(此时用小顶堆,大顶堆可用于取最大值)。

[Blog][Domain] programb.blog.youkuaiyun.com 1072

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

位图排序算法(计数排序)

对对一个最多可以是1千万个数字的集合的数组排序,最大数字1千万,数字不重复(若数字重复,可将byte换成int,进行累加)。 优缺点:优点是快速、占用资源少,缺点是只能对整数使用。 算法: 1. 创建一个bytes[n], n=1千万; 2. 遍历数组,将数组中的数字所对应的位标记为1; 3. 遍历bytes[n],将标记为1的索引(即数组中的数字)输出。 public c

cinnndy的专栏 992

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

海量数据排序

问题: 假设一个文件中有9 亿条不重复的9 位整数,现在要求对这个文件进行排序。 一般解题思路: 1 、将数据导入到内存中 2 、将数据进行排序 (比如插入排序、快速排序) 3 、将排序好的数据存入文件 难题: 一个整数为4 个字节 即使使用数组也需要900,000,000 * 4byte = 3.4G 内存 对于32 位系统,访问2G 以上的内存非常困难,而且一般设备也没

三言两语 1190

Java数据结构与算法(排序)——基数排序(LSD)

一、基本思想 先从最低位开始排序,再对次低位排序,直到对最高位排序后得到一个有序序列(位数不同时高位补 0)。 二、举例分析 假设有一串数列:73, 22, 93, 43, 55, 14, 28, 65, 39, 81。排序过程如下: (1)先根据个位进行排序,得到: 0—— 1——81 2——22 3——73,93,43 4——14 5——55,65 6—— 7—— 8——28 9——39 (2...

kezhou的博客 994

1174: 长整数排序(指针专题)

1174: 长整数排序(指针专题) 时间限制: 1 Sec 内存限制: 128 MB 提交: 2176 解决: 893 [状态] [讨论版] [提交] [命题人:admin] 题目描述 长整数排序。输入n 然后输入n个位数不超过100位的大整数,输入的整数可能含有前导0。将这n个长整数排序后输出,输出不含前导0。 int greater(char *s1, char *s2) { 若s1指向的...

YGGZZZ的博客 514

基数排序&堆排序

基数排序 按照各个数字位数进行排序,分为LSD(最低位优先)和MSD(最高位优先)两种。复杂度为\(O(d(n+k))\),其中\(d\)为最大位数,\(n\)为排序数量,\(k\)为基数的种数。 #include <iostream> #include <algorithm> #include <cstring> using namespace st...

267

基数排序(Java)

基数排序(Java) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 基数排序(桶排序)介绍 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法 基数排序(Radix Sort)是桶排序

归子莫的博客 909
上一篇: 数学之美系列 布隆过滤器(Bloom Filter)
下一篇: Redis Cluster原理
畅想曲
博客等级 码龄20年 2粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值