`

编程珠玑 第1章 有限内存排序问题

阅读更多

准确的问题描述:

输入:一个最多包含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);
		
		
	}

}

 

分享到:
评论

相关推荐

    编程珠玑源码下载编程珠玑书后源代码

    编程珠玑书后源代码编程珠玑书后源代码编程珠玑书后源代码编程珠玑书后源代码编程珠玑书后源代码编程珠玑书后源代码

    编程珠玑 编程珠玑 编程珠玑 编程

    我觉得不错,和大家分享! 编程珠玑 编程珠玑 编程珠玑

    编程珠玑编程珠玑

    编程珠玑编程珠玑

    编程珠玑 编程珠玑续

    编程珠玑和编程珠玑续两本,上传赚点分,填充填充填充

    编程珠玑之位图排序

    输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,。... 约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。

    编程珠玑之第二章questionC 测试数据

    本资源只是“编程珠玑之第二章questionC: 求变位词问题”的简单的测试数据。

    编程珠玑(续)

    《编程珠玑(续)》是计算机...书中涵盖了程序员操纵程序的技术、程序员取舍的技巧、输入和输出设计以及算法示例,这些内容组成一个有机的整体,如一串串珠玑展示给程序员。  《编程珠玑(续)》适合各级程序员阅读参考。

    编程珠玑习题集锦

    书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程...《编程珠玑(第2版)》是计算机科学方面的经典名著。

    编程珠玑续本

    编程珠玑续、编程珠玑续本、编程珠玑续本、编程珠玑续本

    编程珠玑 第二版 修订版

    第一部分 基础 第1章 开篇 3 1.1 一次友好的对话 3 1.2 准确的问题描述 4 1.3 程序设计 4 1.4 实现概要 5 1.5 原理 6 1.6 习题 7 1.7 深入阅读 9 第2章 啊哈! 算法 11 2.1 三个问题 11 2.2 无处不在的二...

    编程珠玑及其源码

    编程珠玑,编程珠玑续以及源码,本书针对程序设计人员探讨了一系列的实际问题,这些问题是对现实中常见问题的归纳总结。作者虽然没有给出解决这些问题的具体代码,但始终非常富有洞察力和创造力地围绕着这些折磨...

    编程珠玑 第2版 kindle格式电子书

    编程珠玑 第2版 azw3格式电子书,适合kindle阅读 Jon Bentley是位于新泽西州Murray Hill的朗讯贝尔实验室计算机科学研究中心的技术委员会委员,Jon自1998年就成为Dr. Dobb's Joumal杂志的特约编辑,他的“编程珠玑”...

    《编程珠玑》源代码

    《编程珠玑》第一版是我早期职业生涯中阅读过的对我影响较大的书籍之一,在书中首次接触到的很多观点都让我长期受益。作者在这一版本中做了重要更新。新增加的很多例子让我耳目一新。 ——Steve McConnell,《代码...

    《编程珠玑 第2版 修订版》

    为此,本书给出了一些精心设计的有趣而且颇具指导意义的程序,这些程序能够为那些复杂的编程问题提供清晰而且完备的解决思路,书中还充满了对实用程序设计技巧及基本设计原则的清晰而睿智的描述。

    编程珠玑.pdf

    第1章 性能监视工具 3 1.1 计算素数 3 1.2 使用性能监视工具 7 1.3 一个专用的性能监视工具 8 1.4 开发性能监视工具 10 1.5 原理 11 1.6 习题 11 1.7 深入阅读 12 第2章 关联数组 13 2.1 Awk中的关联数组 13 2.2 有...

    编程珠玑-第2版-修订版

    本书的特色是通过一些精心设计的有趣而又颇具指导意义的程序,对实用程序设计技巧及基本设计原则进行了透彻而睿智的描述,为复杂的编程问题提供了清晰而完备的解决思路。《编程珠玑(第 2版·修订版)》对各个层次的...

    编程珠玑1和2

    c语言经典书籍,值得拥有

    编程珠玑(第二版)源代码

    编程珠玑 本书针对程序设计人员探讨了一系列的实际问题,这些问题... 本书在第一版的基础上增加了3个方面的新内容:测试、调试和计量,集合表示,字符串问题,并对第一版的所有程序都进行了改写,生成了等量的新代码。

    编程珠玑第二版

    书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程...《编程珠玑(第2版)》是计算机科学方面的经典名著。

Global site tag (gtag.js) - Google Analytics