《编程珠玑》第一章笔记

文章从一个实际的问题开始:一个电话系统,7位数的电话号码,用1MB的内存空间将这些电话号码排序。

分析:如果将这些电话号码看成int类型的整数,将其读入内存中进行排序,int类型4个字节,最多有10000000个电话号码,则需要40MB的内存空间,远远超出题目的要求,但是这10000000个数据有他们的特点:

1、  输入数据限制在相对较小的范围内

2、  数据没有重复

3、  对于每条数据,除了单一整数外,没有其他关联数据

对于此类数据,可以用位图或者位向量来进行排序。

下面是我自己写的一个C程序的片段:

#define MAXN 10000000
#define Byte 8
#define MASK 0x7
#define MOVE 3
char bitMap[MAXN/Byte+1];
void set(int n) { bitMap[n>>MOVE] |=1<<(n&MASK); }
void test(int n) { bitMap[n>>MOVE]& (1<<(n&MASK)); }

这种方法将会用去1.25MB的内存空间。

扩展问题一:当内存空间严格限制在1MB以内,怎样实现排序?

利用两趟算法:先对5000000一下的数字进行排序,然后对5000000以上(包括5000000)进行排序。

扩展问题二:假如每个数不是出现1次,而是出现10次,怎么去解决?

2^4=16>10,因此使用半个字节记录一个数字,总共需要5000000个字节,需要5MB的内存空间,如果内存有1MB的严格限制,那么就要使用多趟算法,用5趟可以解决。

扩展问题三:现在免费区号扩大到800、877、888,以后还会扩展,你怎么用1MB左右的内存空间,对所有免费的电话号码进行排序?如何将免费的电话号码存储在一个集合中,实现快速查找。

我们可以将电话号码的前3个数看成对免费电话号码的分类。首先进行一趟扫描,将号码分类于三个文件中,然后利用位图算法对每个文件进行排序。对于查找,如果内存没有严格的限制,可以将一类数据导入内存,利用二分查找。

总结:

对于空间要求严格的,可以利用位图算法来节省空间,多趟算法可以利用时间换取空间。

你可能感兴趣的:(编程,算法,存储,扩展,byte,电话)