这是《编程珠玑》第一章的一个小问题。
该问题要给一个很大的磁盘文件排序。首先要弄明白该问题的输入输入,以及约束条件。
- 输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。
- 输出:按升序排列的输入整数的列表。
约束:最多有大约1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10s就不需要进一步优化了。
40趟算法
40趟算法读入输入文件多次,写输出文件一次,不需要中间文件。
- 第一次读取:0~249999之间的数,然后排序,输出
- 第二次读取:250000~499999之间的数,然后排序,输出
- …
每次读取所需要的内存大小为:250000*4/1024/1024 约为 0.95MB
位排序算法
位排序算法读入文件一次,写输出文件一次,不使用中间文件。这里,用一个10^7位长的内存来表示一个所有元素都小于10^7的非负整数集合。
例如:{0,1,2,4,5,6} => 1 1 1 0 1 1 1 0 0 0 0
其中第0,1,2,4,5,6位为1
这样,就可以用10^7位 => 10^7/8/1024/1024 约为 1.2MB 的内存来表示全部的数。
- int[] arr = new int[10000000/32],创建一个大小为10000000bit的数组,用来存放数据。
- 每读取一个数i,调用set(i)函数,将第i个位置1,直到全部读取完毕。
- 从第一个数开始,依次调用test(i),若返回值为1,输出i
1 | import java.io.BufferedReader; |