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

本文是《编程珠玑》系列的第二篇,探讨了多个经典算法问题,包括查找缺失整数、一维向量旋转、变位词识别等,并提供了相应的解决方案。文章还涉及到算法的时间复杂度和实际应用中的性能比较。
摘要由CSDN通过智能技术生成

这篇文章是[《读薄<编程珠玑>》系列博客][1]的第 贰 篇,在这篇文章中,作者提出了三个问题,并且给出了相应的解决方案,本文阐述了这三个问题以及解决方案,并且对课后习题进行了分析。

问题集合

  • 0x00: 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(在文件中至少缺失一个这样的数)。在具有足够内存的情况下,如何解决该问题?如果有几个外部的『临时』文件可用,但是仅有几百字节的内存,又该如何解决该问题?

  • 0x01: 将一个 n 元一维向量向左旋转 i 个位置。例如,当 n=8, i=3 时,向量 abcdefg 旋转为 defgabc。简单的代码使用一个 n 元的中间向量在 n 步内完成该工作。你能否仅适用数十个额外字节的存储空间,在正比于 n 的时间内完成向量的旋转?

  • 0x02: 给定一个英语字典,找出其中的所有变位词的集合。例如,『pots』、『stop』、『tops』互为变位词,因为每个单词都能通过改变其他单词中的字母顺序来获得。

  • 0x03:考虑查找给定输入单词的所有变位词问题。仅给定单词和词典的情况下,如何解决该问题?如果有一些时间和空间可以在响应任何查询之前预先处理字典,又会如何?

  • 0x04:给定包含 4,300,000,000 个 32 位证书的顺序文件,如何找出一个至少出现两次的整数?

  • 0x05:前面涉及了两个需要经敲代码来实现的向量旋转算法。将其分别作为独立的程序实现。在每个程序中,i 和 n 的最大公约数如何出现?

  • 0x06:几位读者指出,既然所有的三个旋转算法需要执行的运行时间都正比于 n,杂技算法的运行速度显然是求逆算法的两倍。杂技算法对数组中的每个元素仅存储和读取一次,而求逆算法需要两次。在实际的计算机上实验以比较两者的速度差异,特别注意内存引用位置附近的问题。

  • 0x07:向量旋转算法将向量 ab 变为 ba。如何将向量 abc 变为 cba?(这对交换非相邻内存块的问题进行了建模)

  • 0x08:20世纪70年代末期,贝尔实验室开发出了『用户操作的电话号码簿辅助程序』,该程序允许雇员使用标准的按键电话在公司电话号码簿中查找号码。

    要查找该系统设计者的名字 Mike Lesk,可以按『LESK*M*』(也就是『5375*6*』),随后,系统会输出他的电话号码。这样的服务现在随处可见。该系统中出现的一个问题是,不同的名字有可能具有相同的按键编码。在 Lesk 的系统中发生这种情况时,系统会询问用户更多的信息。给定一个大的名字文件时(例如标准的大城市电话号码簿),如何定位这些『错误匹配』呢?(当 LESK 在这种规模的电话号码簿上做实验时,他发现错误匹配的概率仅仅是0.2%)如何实现一个以名字的按键编码为参数,并返回所有可能的匹配名字的函数?

  • 0x09:在20世纪60年代早期,Vic Vyssotsky 与一个程序员一起工作,该程序员需要转置一个存储在磁带上的4000*4000的矩阵(每条记录的格式相同,为数十个字节)。他的同事最初提出的程序需要运行50个小时。Vyssotsky 如何将运行时间减少到半小时呢?

  • 0x10:给定一个 n 元实数集合、一个实数 t 和一个整数 k,如何快速确定是否存在一个 k 元子集,其元素之和不超过 k ?

  • 0x11:顺序搜索和二分搜索代表了搜索时间和预处理时间之间的折中。处理一个 n 元表格时,需要执行多少次二分搜索才能弥补对表进行排序所消耗的预处理时间?

方案集合

0x00

该问题的解思想在于:二分法

首先,将40亿个数字遍历一遍,分为 2 组,第一位为 1 的一组,为 0 的一组(假设只缺少一个数字),则数量少的一组必定有缺少的数,然后对该组再次进行分组,如此进行下去直到找到该缺少的数字。

如果有足够的空间使用第一章中介绍的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值