准确的问题描述:
输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7(one million)。在输入文件中没有任何两个 数相同。
输出:按升序排序的输入整数列表。
约束条件:1M的内存空间,有充足的磁盘空间,运行时最多需要几分钟,运行时间为10秒不需要优化。
问题分析:如果每个数字用32位整数来存储,1M的空间可以存储 250,000个整数,失少需要10^7 / 250,000
次排序来完成所有的排序,第一次排序0~249999,第四十次排序 97,5000~999,999。
优点:不必使用中间文件。
缺点:需要读取文件40次。
书中通过位图或者位向量来表示集合,例如集合{1,2,3,5,8,13}
可通过如下的位图来表示:0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0
java可以通过逻辑运算来实现位向量操作:具体代码如下:
package org.mino.perl.sort; /** * 位逻辑运算实现位向量 * @author DingJie */ public class BitSet { private static final int BITPERWORD = 32; private static final int SHIFT = 5; private static final int MASK = 0x1F; public static final int N = 10000000; private static int a[] = new int[1 + N/BITPERWORD]; //设置数组第i位为1 public static void set(int i) { a[i>>SHIFT] |= (1<<(i&MASK)); //相应的字节置位,实现对字节的操作 } //清空数组第i位为0 public static void clr(int i) { a[i>>SHIFT] &= ~ (1<<(i&MASK)); } //查询数组第i位数字 是否为1 public static int test(int i) { return a[i>>SHIFT] &(1<<(i&MASK)); } }
在进行大量数据排序之前需要对随机生成1百万个数据,其方法如下所示:
package org.mino.perl.sort; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Random; /** * 获取随机数 * @author DingJie */ public class RandomNum { /** * @param args */ public static void main(String[] args) { // RepeatedRandomNumber(); try { randomNoRepeat(999999,1000000); } catch (IOException e) { e.printStackTrace(); } } private static int randInt(int i, int j, Random rand) { if (i < j) return i + rand.nextInt(j - i + 1); return i; } private static void randomNoRepeat(int m, int n) throws IOException { int[] array = new int[n];//最大的数组 Random rand = new Random(System.currentTimeMillis()); System.out.println(System.currentTimeMillis()); for (int i = 0; i < n; i++) array[i] = i + 1; //赋初值,保证不重复 for (int i = 0; i < m; i++) { int j = randInt(i, n - 1, rand);//返回从i 到n-1之间的任意随机数 int temp = array[j]; array[j] = array[i]; array[i] = temp; } FileWriter fw = new FileWriter("D:/randomNoRepeat.txt"); for (int i = 0; i < m; i++) { System.out.println(array[i]); fw.write(array[i] + ""); fw.write("\r\n"); fw.flush(); } if(fw != null) { fw.flush(); fw.close(); } } /** * 有重复的随机数 */ private static void RepeatedRandomNumber() { // TODO Auto-generated method stub long timeBegin = System.currentTimeMillis(); Random rand = new Random(System.currentTimeMillis()); int bigNum = 1000000; BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter("D:/input.txt")); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while((--bigNum) > 0) { int randInt = Math.abs(rand.nextInt(1000000)); String strRand = randInt + ""; try { bw.write(strRand); System.out.println(strRand); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } } long timeEnd = System.currentTimeMillis(); System.out.println(timeEnd - timeBegin); } }
这样就可以对百万数据进行排序,可以使用java自带的BitSet
package org.mino.perl.sort; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.BitSet; public class BitSortWithUtil { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final int N = 10 ^ 7; BitSet bs = new BitSet(N); File file = new File("D:/randomNoRepeat.txt"); FileReader fr = null; BufferedReader bf = null; int total = 0; try { fr = new FileReader(file); bf = new BufferedReader(fr); String temp = null; while((temp = bf.readLine()) != null) { total ++; int intTemp = Integer.parseInt(temp.trim()); bs.set(intTemp); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(bf != null) { bf.close(); } if(fr != null) { fr.close(); } } catch (IOException e) { e.printStackTrace(); } } int count = bs.size(); int not_count = 0; for(int i = 0; i < count; i++) { if(bs.get(i)){ // System.out.println(i); } else { not_count ++; System.out.println(i); } } System.out.println("not :" + not_count); System.out.println("total :" + (count-not_count) + " /" + total); } }
自定义位向量
package org.mino.perl.sort; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /** * 实现位排序 * @author DingJie */ public class BitSort { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub File file = new File("D:/randomNoRepeat.txt"); FileReader fr = null; BufferedReader bf = null; int total = 0; for(int i=0; i < BitSet.N; i++) { BitSet.clr(i); } try { fr = new FileReader(file); bf = new BufferedReader(fr); String temp = null; while((temp = bf.readLine()) != null) { total ++; int intTemp = Integer.parseInt(temp.trim()); BitSet.set(intTemp); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(bf != null) { bf.close(); } if(fr != null) { fr.close(); } } catch (IOException e) { e.printStackTrace(); } } int count = 0; for(int i = 0; i < BitSet.N; i++) { if(BitSet.test(i) == 1) { count ++; System.out.println(i); } } System.out.println("total :" + count + " /" + total); } }
相关推荐
《编程珠玑 第2版(修订版)》是一本深受程序员喜爱的经典著作,它不仅提供了丰富的编程实践经验,还深入探讨了程序设计的艺术与智慧。这本书的修订版更是在原版基础上进行了更新和完善,旨在帮助程序员提升编程技能,...
《编程珠玑》分为两个部分:第一部分介绍了基本概念和技术;第二部分则通过具体的案例来深化理解这些技术的应用。 ### 二、关键知识点概述 #### 1. 算法分析 - **时间复杂度**:衡量算法执行时间随输入规模增长而...
《编程珠玑》是计算机科学领域的一本经典之作,作者是Jon Bentley,它以其独特的视角和深入浅出的讲解方式,向读者展示了编程艺术的精髓。这本书的第二版更是深受程序员和计算机科学家们的喜爱,因为它不仅涵盖了...
《编程珠玑》第二版是计算机科学领域的一本经典著作,由Jon Bentley撰写,它以其深入浅出的方式探讨了程序设计中的诸多问题和解决方案。这本书不仅涵盖了算法和数据结构,还涉及了软件工程的实践与智慧,对于程序员...
例如,书中探讨了如何设计和实现高效的排序算法,如快速排序、归并排序等,以及如何在有限的内存条件下进行大规模数据处理。此外,还涉及到了查找技术,包括二分查找、哈希表和B树等,这些都是数据存储和检索的基础...
《编程珠玑》是计算机科学领域的一本经典之作,作者Jon Bentley通过一系列实际问题的探讨,引导读者理解和掌握编程中的高效解题技巧。书中的问题和解决方案涵盖了算法设计、数据结构优化以及问题解决策略等多个方面...
《编程珠玑源代码》是针对经典书籍《编程珠玑》第二版的源代码集合,主要涵盖C语言和C++编程。这本书以其独特的视角和深入浅出的讲解方式,深受程序员喜爱,尤其对于数据结构、算法和程序设计思维的提升有着重要的...
#### 三、第一章:开篇Cracking the Oyster - **核心问题**:如何对一个磁盘文件进行排序。 - **思维陷阱**:本章首先提出了一个关于排序的具体问题,但通过这一问题引出了更深层次的概念——在解决问题之前,必须...
本书分为多个部分,第一部分通常聚焦于算法设计和分析的基础,如排序和搜索问题。例如,书中可能会介绍快速排序、归并排序等经典排序算法,以及二分查找、哈希表查找等高效搜索技术。这些知识点不仅在面试中常见,也...
《编程珠玑》第二版在第一版的基础上进行了更新和扩展,包含了更多现代编程实践的案例和思考,如动态规划、遗传算法等高级问题解决策略。同时,书中也加入了对面向对象编程、数据库设计和并行计算等领域的讨论,使得...
在第一章中,可能会有如何使用位图来表示和操作大量数据的示例,例如解决“在一个大整数集合中查找特定元素”的问题。 2. **归并排序(Merge Sort)**:归并排序是一种分治算法,它将大问题分解为小问题进行解决,...
作者精心挑选了一系列看似简单却又富有深意的编程问题,例如在有限的内存条件下如何处理大规模数据、如何快速查找与排序等。通过这些问题的探讨,不仅帮助读者掌握基础的数据结构知识,如数组、链表、树和图,还引导...
《编程珠玑》是计算机科学领域的一本经典著作,作者是Jon Bentley。这本书以其独特的视角,深入浅出地探讨了程序设计中的一些核心问题,并提供了许多实用的解决方案。第二版中,作者不仅保留了原书的精华,还更新了...
《编程珠玑(Programming Pearls)》是计算机科学领域中一本经典的著作,由Jon Bentley编著,第二版进一步丰富和完善了第一版的内容。这本书被誉为程序员的智慧结晶,它不仅仅是一本关于编程技巧的书,更是一本探讨...
《编程珠玑第二版》是程序设计领域里一本极具影响力的著作。这本书以其深入浅出的讲解和富有洞见的分析,深受程序员和计算机科学爱好者的喜爱。书中涵盖了许多编程实践中的核心问题,如数据结构、算法优化、问题解决...
书中的每个章节都围绕一个具体的编程问题展开,这些问题既具有趣味性,又具有实用性,例如,如何快速排序大量数据,如何在有限的内存中处理大规模的数据,如何优化查找和插入操作等。这些问题的解决不仅需要扎实的...