1. 问题描述

输入: 一个最多包含n个不重复的正整数的文件,其中每个数都小于n,每个数是一个7位的整数, n=10^7。

条件: 最多有1MB的内存可用, 排序最多只允许执行几分钟,10s是比较理想的运行时间.有充足的磁盘存储空间可用.

输出: 按升序排列的输入整数的列表.

2. 解决方案

2.1 归并排序

由于内存的限制, 只能采用多路归并的方法来解决这个问题.

排序方法; 把这个文件分为若干大小的几块,然后分别对每一块进行排序,最后完成整个过程的排序。k趟算法可以在kn的时间开销内和n/k的空间开销内完成对最多n个小于n的无重复正整数的排序。比如可分为2块(k=2,1趟反正占用的内存只有1.25/2M),1~4999999,和5000000~9999999。先遍历一趟,首先排序处理1~4999999之间的整数(用5000000/8=625000个字的存储空间来排序0~4999999之间的整数),然后再第二趟,对5000001~1000000之间的整数进行排序处理。

排序步骤:

(1) 内存排序: 由于要求的可用内存为1MB,那么每次可以在内存中对250K的数据进行排序,然后将有序的数写入硬盘。那么10M的数据需要循环40次,最终产生40个有序的文件。

(2) 归并排序:

  1. 将每个文件最开始的数读入(由于有序,所以为该文件最小数),存放在一个大小为40的first_data数组中;
  2. 选择first_data数组中最小的数min_data,及其对应的文件索引index;
  3. 将first_data数组中最小的数写入文件result,然后更新数组first_data(根据index读取该文件下一个数代替min_data);
  4. 判断是否所有数据都读取完毕,否则返回2。

实现过程中, 需要多次读写文件.

2.2 位图方案

数据表示: 使用一个具有1000万个位的字符串来表示输入文件数据, 其中,当且仅当整数i在文件中存在时,第i位为1.

采用位图原因: 利用了该问题在排序问题中不常见的3个属性:

  • 输入数据限制在相对较小的范围内
  • 数据没有重复
  • 对于每条记录而言, 除单一整数外, 没有任何其他关联数据

位图解决三个步骤:

  • 第一步, 将所有位置为0, 从而将集合初始化为空
  • 第二步, 读入文件中的每个整数来建立集合, 将每个对应的位置为1
  • 第三步, 检验每一位, 若该位为1, 就输出相应的整数, 由此产生有序的输出文件

其伪代码如下;

//第一步,将所有的位都初始化为0
for i ={0,....n}      bit[i]=0;
//第二步,通过读入文件中的每个整数来建立集合,将每个对应的位都置为1。
for each i in the input file     bit[i]=1;  //第三步,检验每一位,如果该位为1,就输出对应的整数。
for i={0...n}      if bit[i]==1        write i on the output file  

java实现代码如下:

/** 位向量的实现及其应用在1000万个数的排序中*/
public class Bitvector {public static void main(String[] args){int number = 10000000; //待排序数的数量int len = (number - 1)/32 +1; //java中int占4字节,一位代表一个数,分配多少个int型变量int[] a = new int[len];int[] data = new int[number];//产生随机输入数据,数据是乱序的int temp,temp1;Random rand = new Random();for(int i=0;i<10000000;i++){data[i] = i;//随机交换temp = rand.nextInt(i+1);temp1 = data[temp];data[temp] = data[i];data[i] = temp1; }for(int i=0;i<len;i++){a[i]=0;}for(int i=0;i<number/10;i++){set(a,data[i]);}for(int i=0;i<number/10;i++){if(read(a,i)==1)System.out.print(i+" ");} }//将第i位置为1public static void set(int[] num,int i){num[i>>5] |= (1<<(i&0x1F)); //i>>5指的是i/32,确定其在哪一个int中,i&0x1F则是i%32,确定其在int中的哪一位}//将第i位置为0public static void clr(int[] num, int i){num[i>>5] &= ~(1<<(i&0x1F));}//读取第i位,判断是0/1public static  int read(int[] num,int i){return num[i>>5] & (1<<(i&0x1F));}
}

上述java实现的是对100万个数据进行排序, 这些数据的大小在1000万之间, 由于限制了内存只有1M, 而1000 0000/(8*1024*1024)>1M, 故实现时应该分2趟进行排序,即

  • 第一次,只处理1—4999999之间的数据,这些数都是小于5000000的,对这些数进行位图排序,只需要约5000000/8=625000Byte,也就是0.625M,排序后输出。
  • 第二次,扫描输入文件时,只处理4999999-10000000的数据项,也只需要0.625M(可以使用第一次处理申请的内存)。
    因此,总共也只需要0.625M

***位图的适用范围仅限于针对不重复的数据进行排序.

如何给1000万条记录排序,每条记录都是7位的整数相关推荐

  1. mysql单表1000万条_mysql单表千万条数据测试

    软件环境:win7,mysql版本5.5,InnoDB存储引擎. 硬件环境:普通笔记本,CPU P8700双核2.53GHz,内存3G,5400转机械硬盘1000GB. 建了一张表,id列是自增长bi ...

  2. 1000并发 MySQL数据库_再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化...

    继上篇文章<绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来>发布后在博客园首页展示得到了挺多的阅读量,我这篇文章就是对上篇文章的千万级数据库表在高并发访问下如何进行 ...

  3. 再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化

    原文:再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化 继上篇文章<绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来>发布后在博客园首页展示 ...

  4. java sql 写入万条数据_如何快速向数据库插1000万数据?4种方法对比,它简单却速度最快

    目录 场景介绍 项目配置 Mybatis为什么慢? JdbcTemplate让我眼前一亮 原生JDBC就是快啊! 存储过程怎么样? 越简单越快 前言 一直有一种说法:批量插入大量数据到MySQL数据库 ...

  5. 面试题-批量向MySQL导入1000万条数据有什么方法?

    批量向MySQL导入数据 直接导入 使用存储过程循环拼接 使用load data infile 修改ENGINE=InnoDB为MyISAM(v5.1之前是MyISAM,之后是InnoDB) 减少IO ...

  6. 量化投资:记录自己知与行的实操,通过量化实践,用7年从0打造一个1000万的组合

    知与行,理解和实践盈亏同源的理论.通过量化投资以最小的风险获取最高的收益是这个组合的道与术.按量化指数模型构建一个1000万组合的流程和方法,实践在量化投资之路上积小胜为大胜,最终实现7年1000万的 ...

  7. 绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来

    我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: ...

  8. akka 异常处理_使用Akka处理1000万条消息

    akka 异常处理 Akka演员承诺并发. 有什么更好的模拟方法,看看使用商品硬件和软件处理1000万条消息需要花费多少时间,而无需进行任何低级调整.我用Java编写了整个1000万条消息的处理过程, ...

  9. 使用Akka处理1000万条消息

    Akka演员承诺并发. 有什么更好的模拟方式,看看使用商品硬件和软件处理1000万条消息需要花费多少时间,而无需进行任何低级调整.我用Java编写了整个1000万条消息的处理过程,整个结果令我惊讶. ...

最新文章

  1. 写给大数据开发初学者的话
  2. 那些视觉上骗了你的东西,你上当了吗?
  3. mysql group by cube_SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE
  4. Golang的GC和内存逃逸
  5. Linux 用户磁盘空间配额管理
  6. C#复习笔记(3)--C#2:解决C#1的问题(泛型)
  7. 2022年中国研究生数学建模竞赛
  8. 数据分析的价值是什么?如何做好数据分析?
  9. 强化学习读书笔记(一)
  10. 亲手打造自己的 Linux 桌面环境
  11. 如何高效设计游戏——游戏伤害公式的量身定做
  12. win10关闭动态磁贴_磁贴怎么用
  13. 卸载wps后桌面上的office文件图标变成了白色(亲测有效)
  14. matlab粒子群加约束条件_粒子群算法(PSO)MATLAB实现
  15. c++ primer 第五版 翻译 第一章
  16. 我读过的最好的epoll讲解--转自”知乎“
  17. 稳定成就电子商务未来
  18. pycharm 新建项目时要勾选inherit global site-packages!pycharm 新建项目时要勾选inherit global site-packages
  19. 疑难杂症--WPS文件清理
  20. 行业分析-全球与中国高端厨具市场现状及未来发展趋势

热门文章

  1. 软件测试 毕业设计任务书,软件测试任务书
  2. 达内python培训费_达内python的费用是多少?学习时间长吗?
  3. Sublime text编辑器的使用及快捷键的汇总
  4. 10-SA8155-QNX 中间件之Protobuf/Fdbus交叉编译
  5. 《机器视觉与算法》学习笔记(一)——图像的采集
  6. Python:27画叮当猫—哆啦A梦
  7. 猿人学-Android端爬虫比赛第五关【双向认证】解题笔记
  8. Allegro文件导入SIwave仿真的三种方法
  9. 人在美国,刚下飞机,“IP属地”催生下的灰色产业
  10. MPLS virtual private network报文转发过程