如何给100亿个数字排序?
来源:互联网 发布:我的世界linux版 编辑:程序博客网 时间:2024/05/16 06:10
场景
之前写过一篇海量数据中统计ip出现次数最多的博客,今天再写篇类似的,当然会有不同的地方,相同的地方我快速写过,详细的可以看之前的博客。
今天要给100亿个数字排序,100亿个 int 型数字放在文件里面大概有 37.2GB,非常大,内存一次装不下了。那么肯定是要拆分成小的文件一个一个来处理,最终在合并成一个排好序的大文件。
实现思路
1.把这个37GB的大文件,用哈希分成1000个小文件,每个小文件平均38MB左右(理想情况),把100亿个数字对1000取模,模出来的结果在0到999之间,每个结果对应一个文件,所以我这里取的哈希函数是 h = x % 1000,哈希函数取得"好",能使冲突减小,结果分布均匀。
2.拆分完了之后,得到一些几十MB的小文件,那么就可以放进内存里排序了,可以用快速排序,归并排序,堆排序等等。
3.1000个小文件内部排好序之后,就要把这些内部有序的小文件,合并成一个大的文件,可以用二叉堆来做1000路合并的操作,每个小文件是一路,合并后的大文件仍然有序。
- 首先遍历1000个文件,每个文件里面取第一个数字,组成 (数字, 文件号) 这样的组合加入到堆里(假设是从小到大排序,用小顶堆),遍历完后堆里有1000个 (数字,文件号) 这样的元素
- 然后不断从堆顶拿元素出来,每拿出一个元素,把它的文件号读取出来,然后去对应的文件里,加一个元素进入堆,直到那个文件被读取完。拿出来的元素当然追加到最终结果的文件里。
- 按照上面的操作,直到堆被取空了,此时最终结果文件里的全部数字就是有序的了。
最后我用c++写了个实验程序,具体代码在这里可以看到。
思维拓展
类似的100亿个数字求和,求中位数,求平均数,套路就是一样的了。
求和:统计每个小文件的和,返回给master再求和就可以了。
求平均数:上面能求和了,再除以100亿就是平均数了
求中位数:在排序的基础上,遍历到中间的那个数就是中位数了。
作者:ck2016
原文链接:http://www.jianshu.com/p/8dc11152f178
著作权归作者所有,已获得作者授权转载
原文链接:http://www.jianshu.com/p/8dc11152f178
著作权归作者所有,已获得作者授权转载
0 0
- 如何给100亿个数字排序?
- 如何给100亿个数字排序?
- 如何给100亿个数字排序?
- 给15个数字排序
- 100亿个数字排序
- 如何给10^7个不同的数字的磁盘文件排序
- 15电气李丹【给15个数字排序】
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- C++实现100个数字排序
- 从1亿个数字中取出最大的100个数字- 位图排序(空间换时间)
- 点击浏览器的返回按钮或手机的返回按钮让页面刷新
- 基础总结篇之二:Activity的四种launchMode
- Redis Cluster学习整理
- torch入门笔记9:function
- 如何删除不想要的字符串和符号?
- 如何给100亿个数字排序?
- 学习Spring Security的过程中遇到的问题汇总
- Android UI/UE体验改善
- 第二本 第一章上机4聚美优品
- 建造者模式(Builder Mode)
- 利用tomcat-redis-session-manager解决tomcat的分布式session问题
- 三种工厂模式的使用选择
- 关于在VS2013中添加头文件和lib的路径
- CSDN博客成长记录