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

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

开篇提出了一个排序问题

问题描述:在一个磁盘文件中存在10000000左右个正整数,不存在重复元素,每个数在区间[1,  10000000]中。

输出:将这些整数升序排列,并存到一个磁盘文件里。

约束:大约有1M的内存空间可用,运行时间在10秒左右。

分析:对于1千万左右的数字,我们至少要用4个字节来存储。如果同时将1千万个这样的数字读入内存,大约需要38M左右的内存,

这远远超过题目要求。这种情况下,需要对磁盘文件进行多趟的排序,这样的话代码会很复杂,而且很难满足时间要求。

解决方法:文中提出用位图(或者叫位向量)来表示集合。比如,数字集合{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}。可见将位图中第i位置为1,来表示数字i。如例子中位图的第1,2,3,5,8, 13位被置为1.

位图的优点

  1. 节省内存空间。对于题目中的1千万个数据,只需要1千万位(1M左右)的内存就可以满足要求。
  2. 省略了排序过程。位图本身就有顺序,因此满足时间要求。

相关代码:

这是书中给的参考代码:

#include <iostream>
#include <cmath>
using namespace std;

#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
unsigned int a[1 + N/BITSPERWORD] = {0}; 


//将位图的第i位置为1 
void set(unsigned int i){
	a[i >> SHIFT] |= (1 << (i & MASK));
}

//将位图的第i位置为0 
void clr(unsigned int i){
	a[i >> SHIFT] &= ~(1 << (i & MASK));
}

//检查位图第i位 
int test(unsigned int i){
	return a[i >> SHIFT] & (1 << (i & MASK));
}

int main(){
	
	set(32);
	cout << a[1] << endl;
	
	return 0;
}

这是我自己写的代码:

#define N 10000000
bool a[1 + N] = {0};

void myset(int i){
	a[i] = true;
}

void myclr(int i){
	a[i] = false;
}

int mytest(int i){
	return a[i] ? pow(2, i) : 0;
}

int main(){
	
	myset(5);
	cout << mytest(5) << endl;
	
	return 0;
}

问题扩展:

第五题:内存空间不足怎么办?原题中给的内存是1M,如果现在只有0.8M的内存,这时候需要怎么办呢?

解答:由于内存的限制使得不能一次将数据全部读入内存。可以进行多趟读取。比如,进行两趟读取。第一趟只处理1到5百万的数据,第二趟处理5百万到1千万的数据。这样一来,内存只需要0.5M(之前的一半), 而消耗的时间将是之前的两倍。

第六题:如果每个数字可能重复出现,且最多有10个相同的数字该怎么办?

解答:原题中的位图,对于每一位,0表示没有出现,1表示出现。如果一个数字可能出现多次,那么这个数字的状态将会有,出现0次,出现1次, 出现2次,,,出现10次的情况,一共会有11中状态,那么至少需要4位才能表示这11种状态。这种情况下,用4位表示一个数字出现的次数,内存的消耗将会是之前的4倍。

第十题:一个商店的客户名单中,用客户的电话号码为关键字来标记客户资料。请问怎么设计客户资料的数据库,使得对客户资料的插入和检索更为高效?

解答:对于电话号码来说,前面几位数字很有可能出现相同的情况,而最后两位是随机出现的。用10 * 10个箱子组成一个二维矩阵,矩阵的每一行(列)都表示0到9这十个数字,行、列组成电话号码的最后两位,将对应的用户资料放入对应的箱子中。这种思想类似于散列表的思想。通过简答的操作,就可以在效率上提高很多。

编程珠玑 这不是一本具体算法的讲解或者代码编写的教程,但是从书中的字里行间,我们可以学到的是更多的软知识:对编程新的认识、更加发散的思维方式、更严格的代码要求、堪比瑞士军刀的小技巧…… 编程也许入门并不难,但是要想真正成为一名优秀的软件工程师,还是需要很多锤炼。内外兼修,方成大器。 基础篇 第一章 开篇首先作者提出一个实际问题: 如何给磁盘的某个文件排序,更具体来说就是是对一个最多包含1千万条记录,每条 阅读详情

相关推荐

【读薄《编程珠玑》】贰 啊哈!算法

这篇文章是[《读薄<编程珠玑>》系列博客][1]的第 贰 篇,在这篇文章中,作者提出了三个问题,并且给出了相应的解决方案,本文阐述了这三个问题以及解决方案,并且对课后习题进行了分析。 问题集合 0x00: 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(在文件中至少缺失一个这样的数)。在具有足够内存的情况下,如何解决该问题?如果有几个外部的『临时』文件可用,但

远航 | FIBOS.io 4426

编程珠玑 第2版(修订版)_编程珠玑修订_资料_

编程相关文档建议。作者写了编程中的相关注意点,值得一看。在编程中可多注意。

编程珠玑:深入浅出的编程经典

本文还有配套的精品资源,点击获取 简介:《编程珠玑》是一本计算机科学的经典之作,由Jon Bentley撰写。书中不仅详细探讨了数据结构和算法,还深入分析了问题解决策略、编程的艺术与技巧,以及性能优化。书中附带源代码分析,帮助读者通过实际案例理解理论与实践的结合,从而提升编程技能和解决问题的能力。 1. 数据结构与算法详解 简介 数据结构与算法是计算机...

weixin_33072399的博客 1083

MiMo-VL-7B-SFT与其他开源VLM对比:Llava、Qwen-VL、CogVLM全面评测

在当今快速发展的多模态AI领域,**MiMo-VL-7B-SFT**作为小米推出的开源视觉语言模型,以其卓越的推理能力和视觉理解表现脱颖而出。本文将深入对比MiMo-VL-7B-SFT与当前主流的开源VLM模型——Llava、Qwen-VL和CogVLM,帮助开发者和研究者了解各模型的特点、优势与适用场景。 ## 🎯 核心功能对比:四大开源VLM模型 ### 1. MiMo-VL-7B-SF

gitblog_09741的博客 766

编程珠玑 Programming Pearls 第二版(中文版+源代码)

计算机经典书籍——编程珠玑 Programming Pearls

送5本《编程珠玑 第二版》

文末赠书说起IT编程经典,我们总是绕不开《编程珠玑》。距离这本书首次问世已有近40年之久了,中文版也已经出版近15年。以计算机和互联网的发展速度而言,别说是40年,哪怕只有几个月也足够让一项技术更新得“面目全非”。那么这一本1986年就面世的《编程珠玑》,为何至今仍能畅销全球,且被业内大牛誉为编程“奇书”?对于这个问题,我们邀请了一位老朋友——资深技术人高博,来和大家聊聊《编程珠玑》。▲ 点击图片...

a934079371的博客 283

编程珠玑】陪着奶猫看看书--《编程珠玑第一章

陪着奶猫看看书–《编程珠玑第一章 没事吹吹看《编程珠玑》的感受!大家一起讨论讨论!!!

IShadow 1025

编程珠玑》阅读小记(1)— 开篇

1. 前言久闻《编程珠玑》一书的大名,一直没有找到合适的机会深入学习阅读,最近终于得以入手,便决心投入细细的研究,提升一下自己的编程思想与技术。阅读之后才发现,这本书确实一本不可多得的好书。它以计算机领域应用与编程算法相结合,让读者面对实际问题时,不单单局限于考虑该问题的解决方案,而是在入手实践之前能够驻足于考虑,该方案是否符合当前的实际环境,它的时间与空间的消耗是否达到了一个比较好的指标。 通过

指尖飞舞 1600

编程珠玑开篇2--磁盘文件排序问题再讨论

编程珠玑开篇--磁盘文件排序问题一文中,要求输入时某个正整数不会重复出现。 如果每个整数重复出现的次数至多10次,我们应该如何修改方案呢?如果每个整数最多出现10次,那么我们就可以使用半个字节4位,统计出现的次数。相应的设置函数也应该修改: #define BITSPEREORD 8 // the type int contains 8 bit num#define SHIF

fisher_jiang的专栏 1457

1. 编程珠玑笔记一开篇

1.          编程珠玑笔记一开篇 从事于IT行业,如果不会编程,那蛤蟆只能呵呵了。 有些人将编程认识为敲字,所以一直是码农。有些人将编程认识为COPY,所以一直是搬运工。我们不是工程师,我们只是IT的搬运工~ 其实编程可以不一样,是一个洞察力和创造力的集合。需要我们不停磨练编程技巧和基本的设计原理。  欢迎转载,转载请标明出处: 1、     开篇 是一个外部排序的问题,题目

badman250的专栏 3万+

编程珠玑学习收获

很早就买了这本书,不过一直没看,听师哥师姐们说,要想进互联网公司(dui)

读书与思考的乐趣 1644

编程珠玑.pdf

编程珠玑,适合于开发人员的一本基础教材,建议可以通读一遍,会有收获的。

编程珠玑》——开篇

因为该问题的约束条件中描述了输入文件中最多有1千万个不重复的7位数,内存的大小限制位1MB。针对上面的问题,可以构造一个长度为1000万个位的字符串,从输入文件中挨个读取输入,文件中的每个7位数都不会重复,每读入到一个7位数i,便将字符串中的第i位置为1,表示该数字出现了,进行排序的时候,从0开始遍历该字符串,出现1的数代表刚才输入文件中有对应的数值,遍历完该字符串也就是从小到大完成了排序,最后将排序结果输出到输出文件中,便完成了该问题所要求的排序结果。以上就是问题的描述规范,应包含输入、输出和约束。

漫漫编程路 689

编程珠玑第一章Java代码实现

[size=large]我看算法的时候只看伪代码的话,感觉太抽象,总记不住,我希望能看到真正实现的代码,这样心里会感觉踏实一点。 因此,总希望能把书上的算法给具体实现了,这样一来能记住算法,加深印象,而来二来也能提高自己的编程水平。 《编程珠玑》的代码已经有C/C++的实现版本了,我在附件也贴出来了,但是,作为一个C++语言的入门者,因为还涉及到不知道如何链接C++的函数库等种种问...

limitforest1的博客 437

编程珠玑(1)

 这周借了本 “编程珠玑”,书不大,200多页,本以为能一周看完的,结果看完第1章就头大了。在此做点笔记,说不定找工作用得上。第1章,位图排序,一位代表一个数(如a[10]=1 表示数10存在)问题里面还有一个 选择问题,即n个数里随机取k个不同的数。开始看到题目的答案就蒙了,后来想想其实很简单。设数组为a[0]...a[n-1]1、j=n2、i=ran(0,j)     //0..j中随

ipiggg的专栏 2319

编程珠玑 java 答案_编程珠玑(第2版)第一章课后习题答案

第一章 开篇1.#include #include // 输入相同元素在集合内只保留一个using namespace std;int main(){set S;int i;set::iterator j;while( cin >> i )// 输入ctrl + z回车结束输入S.insert(i);for(j = S.begin(); j != S.end(); ++j)// 这里不...

weixin_35655990的博客 351

编程珠玑混搭

感觉编程珠玑写的很好,但是书上写的不尽详细,仿佛如“高手过招,点到为止”,网上查些资料,加上自己的领悟,写写呗。 第一章:参照:http://chaoswork.com/blog/2012/05/18/programming-pearls-study-note-1/ 1.4.如何生成位于0到n-1之间的k个不同的随机顺序的随机整数? Idea1:用set行,主要是set里面的元素不重复,

瀚海一叶 1012

编程珠玑有感!

乔恩,宾利老爷子的神书,我在刷leedcode过程中突然发现,二分查找,二分搜索树之类的东西很牛逼-------使用太多了。于是好好学习,偶然看到编程珠玑,在书堆中找出了编程珠玑。看了一下深以为然!老爷子的水平实在是高,程序验证这门研究生的课,也被他单独列了出来,二分查找更是第一章列出。爱不释手,要深入研读这本书。开篇问题 :磁盘文件排序? 文件最多包含1千万条记录,没条记录都是7位的整数。

fly_best的专栏 676
上一篇: 学习muduo库(15)之socket类
下一篇: 《编程珠玑》学习记录第二章算法
我叫龙傲天
博客等级 码龄10年 51粉丝 118原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值