【编程珠玑】第一章 开篇

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

【编程珠玑】第一章 开篇

一. 题目

      如何给磁盘文件排序?

     问题描述:
     输入:一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,其中每个数都小于等于n,且    n=10^7。
     输出:得到按从小到大升序排列的包含所有输入的整数的列表。
     条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在5分钟以下,10秒为最佳结果。

二.分析

      1)基于磁盘的归并排序(耗时间)

     2)每个号码采用32位整数存储的话,1MB大约可以存储250 000 个号码,需要读取文件40趟才能把全部整数排序。(耗时间)

     3)位图法,采用一个1千万位的字符串表示每个数,比如{0,2,3}表示为   1  0 1 1 0 0 0 0 。(说明:左边第一位表示 0 第二位表示1 第三位表示 2 。如果有则表示为1,否则为0)遍历每一个整数,有则标记为1,否则标记为0。然后按顺序输出每个整数。这种方法实际需要1.25MB内存,如果可以方便弄到内存的话可以采用此种方法。

     4)假如严格限制为1MB,可以采用的策略:两次遍历或者除去第一位为0或1的整数。

         解释:考虑到没有以数字0或1开头的电话号码,可以省略对这些数的操作。

         两次遍历:对  1 ---4999 999之间的数排序,需要存储空间为:5000 000/8 =625 000 字节(8为一个字节中的位数) 对 5000 000 -10000 000 之间的数排序。 如果需要采用k趟算法,方法类似。

三. 算法实现

#include <stdio.h>  

#include <stdlib.h>  

#define SHIFT 5  //表示位移量

#define MASK 0x1F  //掩码

#define N 10000000  //表示有1000万个数

int a[1 + N/32];  //使用整形数组来模拟定义1000万个位的数组

void set(int i) {  a[i>>SHIFT] |=  (1<<(i & MASK)); } //设置位数组中的从0开始的第i位为1 

void clr(int i)  {   a[i>>SHIFT] &= ~(1<<(i & MASK)); }  //设置位数组中的从0开始的第i位为0

int  test(int i) { return a[i>>SHIFT] &   (1<<(i & MASK)); }  //取出从0开始的第i位的值,用于检测

int main()  

{       

       int i = 0;  

        //int  top = 1 + N/BITSPERWORD;  

        //memset(a, 0, sizeof(a)*sizeof(int)); 

       for(i=0;i<N;i++)

           clr(i);

       while (scanf("%d", &i))   

        set(i);  

        for (i = 0; i < N; i++)            

          if (test(i))   

          printf("%d\n", i);  

         return 0;  

}  

四. 参考来源

    1.  http://blog.csdn.net/tianshuai11/article/details/7555563

    2.  http://blog.csdn.net/ju136/article/details/6832331

    3. 《编程珠玑》读书笔记

                    

编程珠玑》习题练习In Python——第一章 开篇 问题:如何给磁盘文件排序 输入:一个包含最多n个正整数文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该数据相关联。 输出:按升序排列的输入整数的列表。 约束:最多有(大约)1MB内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。 阅读详情

相关推荐

算法学习(七)有内存限制的海量数据排序

磁盘文件排序问题描述: 输入:给定一个文件,里面最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数),且其中每个数都小于等于n,n = 10^7。 输出:得到按从小到大升序排列的包含所有输入的整数的列表。 条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在五分钟以下,10秒为最佳结果。 分析: 首先注意的是它的内存要求,基本上否决了大多数的排序算法。 文

shitangdejiaozi的博客 8088

编程珠玑经典题目

1、10*n个整数(亿级)的排序 输入:一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,其中每个数都小于等于n,且n=10^7。 输出:得到按从小到大升序排列的包含所有输入的整数的列表。 《编程珠玑》中提出的问题,有三种解法: (1)磁盘合并排序 先将所有数据分成多个小文件,多个小文件采用内部排序后,再用多路合并排序完成排序输出。 总数据为n, 内存中采用内部排序最多m。先分成n/m个小文件,再内部排序,第三部读取所有小文件,每次将最小的数输出即可。 (2)多通道 0

qq_40310710的博客 326

关于位图排序

输入:   一个包含n个正整数文件,每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。输出:  输入整数的升序排列 约束: 限制在1M左右内存,充足的磁盘空间    假设整数占32位,1M内存可以存储大概250000个整数,第一个方法就是采用基于磁盘的合并排序算法,第二个办法就是将0-9999999切割成40个区间,分40次扫描(10000000/250000

inter999的专栏 2968

编程珠玑(一)

这是学习编程珠玑第一章~ 问题描述: 输入:一个最多包含n个正整数文件,每个数都小于n,其中n=10^7,且所有正整数都不重复。 输出:这n个正整数升序排列输出列表 约束:最多1MB的内存空间,有充足的磁盘存储空间可用,运行时间最多几分钟,运行时间为10秒则不需要优化了。 一、多通道实现: 题目中的限制为所有正整数都不重复。这代表: 输入文件中范围在1~249 999的正整数至多...

weixin_30299709的博客 176

编程珠玑_第一章_ 开篇

问题: 输入:给出至多10,000,000个正整数的序列 特征:每个数都小于10,000,000、数据不重复 且 数据之间不存在关联关系(相互独立) 输出:增序输出序列 约束:内存容量1MB,磁盘空间充足,运行时间至多几分钟,10是最适宜的时间 分析:我们需要10,000,000个数表示10,000,000个位。1MB的包含8*1024*1024个位 则,所需要的内存容量为:10,00

思考,思考,再思考~ 1630

编程珠玑第一章开篇

问题描述:如何给磁盘文件排序? 输入:一个最多包含n个正整数文件,每个数都小于n,其中n=107。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。 输出:按升序排列的输入整数的列表。 约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行10秒就不需要进一步优化了。 实现概要: 这个样的题目咋一看就会想到外部排序的方法。

东方吹雪的专栏 1312

编程珠玑第一章开篇 总结

<br /> 看这本书时,心里默默告诉自己,要好好琢磨,不可求速度,要看自己吸收了多少。<br /> 现在把第一章总结下:<br />当遇到一个问题时,解决的一般原理为:<br />第一:正确的问题。明确问题,这场战役就成功了90%。对问题进行形式化的描述是很关键的,把输入、输出和约束亲手写下来。<br />    输入:一个最多包含n个正整数文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据和该整数相关联。<br />    输出:按升序排列的输入整数的

DeepIT的专栏 886

编程珠玑》学习记录第一章开篇

开篇提出了一个排序问题 问题描述:在一个磁盘文件中存在10000000左右个正整数,不存在重复元素,每个数在区间[1, 10000000]中。 输出:将这些整数升序排列,并存到一个磁盘文件里。 约束:大约有1M的内存空间可用,运行时间在10秒左右。 分析:对于1千万左右的数字,我们至少要用4个字节来存储。如果同时将1千万个这样的数字读入内存,大约需要38M左右的内存, 这远远超过题目要求。这种情况下,需要对磁盘文件进行多趟的排序,这样的话代码会很复杂,而且很难满足时间要求。 解决方法:文中提出.

请叫我少爷的博客 197

编程珠玑第一章 开篇

1.问题描述 输入:一个最多包含n个整数的文件文件中的每个整数都小于n,其中n=10^7。输入文件中没有重复的整数。 输出:按升序排列的整数列表 约束:最多有大约1MB的内存空间,有充足的磁盘存储空间可用。 (1)采用外排序;每次读入一部分数据至内存进行排序,然后对各部分进行归并。 (2)采用位图法;用一个一千万位的bit串来表示所有的整数,从左到右每一位分别代表整数1,2,3

韦远科的专栏 952

编程珠玑第一章开篇——排序

为什么80%的码农都做不了架构师?>>> ...

weixin_34290390的博客 161

编程珠玑第一章开篇

习题 1. 如果不缺内存,如何使用一个具有库的语言来实现一种排序算法以表示和排序集合?

Code for Yun 1382

编程珠玑 第一章 开篇

习题 1. 如果不缺内存,如何使用一个具有库的语言来实现一种排序算法以表示和排序集合?       由于目前只学习了C和C++,所以只讨论C和C++中具有排序算法的库。对于C,有stdlib.h中的快速排序qsort函数;对于C++,其STL中的algorithm包含一个排序算法sort函数。    #include void qsort( void *buf, size_t nu

ChallenChenZhiPeng的专栏 957

编程珠玑读书笔记 第一章 开篇

2013-07-10 18:39:25 【编程珠玑读书笔记第一章   本书以一个排序的问题开篇,讨论了排序的最佳方法,并引入了位图排序的算法。实际上,此处的位图排序本质就是计数排序(关于计数排序,此处不再赘述),只不过由于此处问题的特殊性——数据没有重复,可使用更加节省空间的方法,对每一个数据,使用1bit的空间进行计数。   书中还给出了用标准库函数qsort、以及模板类set排序的提议...

weixin_34122604的博客 95
上一篇: 【2012百度之星资格赛】A:百度计算器的加法
下一篇: gtk/glade程序开发——gtk/glade环境的安装编译与测试
快乐的霖霖
博客等级 码龄15年 1028粉丝 904原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值