《编程珠玑》笔记一

本文是《编程珠玑》笔记的第一部分,探讨如何高效地对1千万条电话号码进行排序,提出了使用位图作为解决方案,以节省内存和提高效率。通过位逻辑运算符实现位向量的操作,简化问题并减少时间复杂度。
摘要由CSDN通过智能技术生成

第一章 开篇

友好的对话

在别人不会问问题时,引导他去问问题也是一个很大的学问,Jon与一个程序员问的问题而展开。

问题

如何将1千万条记录排序?(都是七位的电话号码)最好是将时间控制在十秒钟左右,如果不行,几分钟也可以,但是不能超过十分钟,同时不可超过一兆的内存。

Jon先生要求我思考一分钟,并给他一个答案。我的答案有两个,一是使用链表的方式,运用插入排序的方法,二是使用规定排序的方法(尽管直至此时,我仍没有成功的完成固定排序,但我推荐他这么做的原因是其时间复杂度最低)下面向您简述我了解到的归并排序算法的原理,首先将数组分为两部分,然后将ab两部分分别排序,最后将ab两部分合并为一个数组。
如下图所示。

插入排序的过程如下:

将ab中待插入的元素作比较,将较小的插入L,然后将插入的数组定位器后移,继续比较两个数组的待插入元素,嗯,直到a与b中所有元素全部插入到L中,嗯,此时结束。当然以上并没有说明如何将ab数组排序,这里其实有一个很好的办法,就是将其分割若干次,直至每个数组都是单一元素数组,那么数组遍都是排序排好序的数组。

以上便是我的解答,非常奈斯!

下面是Python的实现代码。
def marge():
    pass

def marge_sort():
    pass

''' 实在是困得不行,明天再写'''
而Jon思考后的解决办法是使用位图,我觉得原因有以下几点:
  1. 1千万条记录又是用一兆的内存直接运行的,怕是不行。
    复习一下组成原理的知识。
    1 Byte = 8 bit
    1 KB = 1024 Byte = 8 * 1024 bit
    1 MB = 1024 KB
    1 GB = 1024 MB
    1 TB = 1024 GB
    二进制数程序中,每个零或一就是一位。位就是bit。
    假使这里运用八位二进制表示一个数字,且每个电话号码都为7位,则有(1024×1024×8) / (8*7) = 143000(Jon老师可能将1000视为1024)。
    Jon的另一种方法似乎可以存放更多的数,即每个号码用32位二进制表示,则有(1000×1000*8) / 32 = 250000,即1M可以存放250000个号码,因为最大的7位数为9999999,便有9999999 / 250000 = 40。嗯,40次才能装得下1000万个电话号码。以上次多趟排序的空间大小分析,多趟排序的原理是第一趟排序中将0-250000之间的任何整数读入内存,并对着25万个整数排序,然后写到输出文件中,重复40次则排序完成。

  2. Jon说此问题若是采用归来排序可能需要几天的时间(包括写程序,调试,运行。我觉得晚上回去可以试一下)。

  3. 位图的方式更加简明记,即将大小为n的数用1占位表示第n个数是存在的,即array[1048256] = 1,即表示电话号码1048256存在。好了,下面来简述一下Jon的方法——位图的方法:
    第一步就是初始化一个大小为一千万的shuzu。
    第二部遍历输入文件。如果某个数存在则设其位置为1。
    第三步,输出答案。

哇哇。真的简单明了,可惜可惜!为什么我们早点想到这个方法,脑中是有闪过这个想法的。但是觉得不成熟也没有在思考,而是转念去想归并排序这个方法了,是什么原因?我觉得是思维不愿意去思考的原因,前几天还看了关于开发思维的书籍,里面讲的:同时从好几个方面来思考方法。不要只从一面来思考。先不着急着否定了某个想法。先记下来。可惜可惜!

但是这个方法好像有问题。不是这个解法有问题,自己该用什么数据结构的存储,Jon首先说用字符串的方式。然后我说用数组的方式,我觉得都可以。好的牛皮!

习题1.6

2.问:如何使用位逻辑运算符(如与,或,移位)来实现位向量?

首先我因为不明白为向量是什么而搜索以下这个问题:“什么是位向量?”,我看了一下百度百科,CSDN的zeb_perfect以及远航先生的博客,我决定自己先来解决问题(笑)。因为百度的解释太深奥,不是看的很懂,zeb_perfect先生解读的可能有些偏差(无意冒犯),远航先生的解读过于深入,暂时不想看。但是我将二位的博客都添加到我的收藏夹下,待我先思考一番之后,且是全面的思考,定是全面的思考,再来拜读二位的博客。好了,废话不多说,先来探究问题,如果Jon先生在我面前,倘若有幸见到先生,那我一定会说:您这是问的什么鸡巴问题?可不可以不要那么抽象呢?而且也不明确。再读一遍问题:“如何使用位逻辑运算符(如与,或,移位)来实现位向量?”我还是不明白要问的是什么?原因以下1.可能是不明白什么是位向量?我的理解是位向量就是位图的延伸,使用多个位来表示一个单位,我们且将其称之为——位向量。哇哇哇~,如此简洁明了,怕是只有张某人能做出这一定义了,好了,不再废话,我的脑海中给出的答案现在有两个,
第一个是假设用四个位为一个单位,那么第一个与第二位的与可以表示一个单位的性质或者属性,那么这个这个位向量可以表示4+n个属性。
第二个通过使用位置位逻辑运算来生成其他几个位(这个也还是可以)。
好了,先到这里吃饭。

第一部分 编 程 技 术 第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 有穷状态机模拟器 16 2.3 拓扑排序 17 2.4 原理 20 2.5 习题 21 2.6 深入阅读 22 第3章 程序员的忏悔 23 3.1 二分搜索 24 3.2 选择算法 26 3.3 子程序库 28 3.4 原理 30 3.5 习题 31 第4章 自描述数据 33 4.1 名字—值对 33 4.2 记录来历 36 4.3 排序实验 37 4.4 原理 39 4.5 习题 39 第二部分 实 用 技 巧 第5章 劈开戈尔迪之结 43 5.1 小测验 43 5.2 解答 44 5.3 提示 44 5.4 原理 47 5.5 习题 48 5.6 深入阅读 49 5.7 调试(边栏) 49 第6章 计算机科学箴言集 51 6.1 编码 52 6.2 用户界面 53 6.3 调试 53 6.4 性能 54 6.5 文档 56 6.6 软件管理 56 6.7 其他 58 6.8 原理 58 6.9 习题 58 6.10 深入阅读 60 第7章 粗略估算 61 7.1 头脑热身 61 7.2 性能的经验法则 62 7.3 Little定律 64 7.4 原理 65 7.5 习题 66 7.6 深入阅读 67 7.7 日常速算(边栏) 67 第8章 人员备忘录 69 8.1 备忘录 69 8.2 原理 71 8.3 深入阅读 71 第三部分 人性化I/O 第9章 小语言 75 9.1 Pic语言 76 9.2 视角 79 9.3 Pic预处理器 81 9.4 用来实现Pic的小语言 83 9.5 原理 87 9.6 习题 88 9.7 深入阅读 89 第10章 文档设计 91 10.1 表格 92 10.2 三条设计原则 94 10.3 插图 94 10.4 文本 96 10.5 合适的媒介 98 10.6 原理 100 10.7 习题 101 10.8 深入阅读 101 10.9 次要问题目录(边栏) 101 第11章 图形化输出 103 11.1 实例研究 103 11.2 显示结果取样 105 11.3 原理 107 11.4 习题 108 11.5 深入阅读 110 11.6 拿破仑远征莫斯科(边栏) 110 第12章 对调查的研究 113 12.1 有关民意调查的问题 113 12.2 语言 114 12.3 图片 117 12.4 原理 119 12.5 习题 120 第四部分 算 法 第13章 绝妙的取样 123 13.1 取样算法一瞥 123 13.2 Floyd算法 124 13.3 随机排列 125 13.4 原理 127 13.5 习题 127 13.6 深入阅读 128 第14章 编写数值计算程序 129 14.1 问题 129 14.2 牛顿迭代 130 14.3 良好的起点 132 14.4 代码 133 14.5 原理 135 14.6 习题 135 14.7 深入阅读 137 14.8 数值算法的力量(边栏) 137 第15章 选择 141 15.1 问题 141 15.2 程序 142 15.3 运行时间分析 145 15.4 原理 148 15.5 习题 149 15.6 深入阅读 151 附录A C和Awk语言 153 附录B 一个子程序库 157 部分习题答案 165 索引 181
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值