一、需求
在美国,电话号码由3位区号与7位其他号码组成。拨打包含800的电话是不收费的。实际的免费电话号码数据库包含有大量的信息,包括免费电话号码、拨打的实际号码、用户名称和地址。
需要建立一个系统来处理这一类数据库,将要进行排序的只是免费电话号码,号码是不重复的。预期输出一个包含大量号码,并升序排序的文件。实际环境与性能需求,讲求频率大约每小时一次,合适的运行时间为10秒。至多1MB可用主存。
二、分析
输入项:0-9999999的整数,不重复。
输出:升序排序后的文件。
约束:1.时间小10秒,2.主存至多1MB。
分析:1M内存,以整型描述(4个字节)一次性最多输入数据为1000000/4=250000个数据,那么0-9999999至少需要分40次输入。
三、位图排序
分析:1字节8位,10000000点用字节1250000为1.25M(实际已经超出1M的限制),每位通过0和1的状态标识第N位是否有数据。
最后通过判断第N位是否为1来输入数据。
initialize: for i=0 to 9999999 bit[i]=0
sort:foreach j in input bit[j]=1
output: for k=0 to n if(bit[k]==1) print(k)
四、问题:
Q:如果构建测试所需要的已经打乱的数据,且要求数据不重得。
A:生成数据,然后根据随机数据调换数据N次
Q:如果强制要求内存在1M以内,如何处理。
A:将文件输入两次,第一次检索0-4999999,第二次检测5000000-9999999,然后再输出文件。
Q:如果每个数据最多可重复10次,怎么进行改进?
A:可以用4位来表该数据存在的次数。
Q:免费号码有800,877甚至还在增加,怎么用1M的空间进行排序和快速定位。
A:每次排序一类号码,比如第一轮排序800,第二轮排序877,通过对排序位标识进行存储(相当于索引),可以快速确定该号码是否存在。