《编程珠玑》读书笔记2------------第二章习题及个人答案

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

为给点单词做标记,如mississippi的标记为(i4m1p2s4)标记内字母按字典序排列,遍历字典,每查询一个单词,同样为其作出标记,做完后比较标记。还有种方式是在做标记的时候就进行判断,如果查询单词中存在字母数量大于目标单词,break,如果存在字母字典序小于目标单词的第一个字母,break。

如果可以预处理,建立森林,根结点依次为字母。


2.给定包含4 300 000 000 个32位整数的顺序文件,如何找出一个出现至少两次的整数?


二叉搜索,每读取一定数据后,先判断首位数据加上数据长度是否等于尾部数据,如果相等,继续读取文件,如果不等,进行搜索,比较中位值与尾部数据+首位数据。如果中位值大,则继续在尾部二分查找,如果中位值小,则继续头部二分查找,如果相等,那么这个数就是重复的数。


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


void moveString(char* string,int n,int i)
{
        for(int j=0;j



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

标准答案:为了转置行矩阵,Vyssotsky为每条记录插入列号和行号,然后调用系统的磁带排序程序先按列排序再按行排序,最后使用另一个程序删除列号和行号。


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


遍历集合,计算每个集合的和,如果和小于t  且已添加的数量小于k则添加到数组,如果大于k了,比较已添加的集合中最大的是否大于这个待添加的集合的和,如果大于则剔除原有的,并把待添加的添加进来,否则不添加,添加的集合采用大顶堆存储。


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

这个就是计算两种方式的平均时间了。






你可能感兴趣的:(《编程珠玑》读书笔记)