编程珠玑读书笔记-第1章

版权声明:本文为 DouMiaoO_Oo 原创文章,未经允许不得转载!

第一章

介绍

本章提出一个问题,电话号码有10位,前3位是固定区号800 ,后面还有7位数字,需要对这些电话号码进行排序。即:

输入: 一个最多包含n个正整数的文件,每个数都小于 n n n ,其中 n = 1 0 7 n =10^7 n=107。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。

输出:按升序排列的输入整数的列表

约束:最多有(大约)1 MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。

从这里我们可出,记录中只有正整数。约束条件是业务需求导致的。这里作者一步步提出了三种方法:

  1. 归并排序,即磁盘中的外部排序,读取一遍输入文件,但是需要多次读写工作文件(中间文件)
  2. 多趟排序,因为1MB能保存 25 K 25K 25K 个数据,所以 1 0 7 10 ^ 7 107 ∈ [ 0 , 1 0 7 ] \in [0, 10 ^ 7] [0,107] 的数可以划分为40个区间,可以通过多次读取输入文件来排序。对于第 i i i 趟读取输入文件,我们可以排序大小在 [ 25 K ∗ ( i − 1 ) , 25 K ∗ i ) [ 25K * (i-1), 25K * i ) [25K(i1),25Ki) 区间内的数。
  3. 位图或者位向量(bit vector/bit map) 来做。

在我目前看来,我觉得位向量和 桶排序(bucket sort)很类似,这里先记录一下。位向量就是一组bit构成的基本数据结构。 我们把可以用的1MB的内存利用二进制展开,这样能够得到的bit数目有 1024*1024*8 = 8,388,608。位向量就是指,从左往右看对于第i 个比特,如果这一位是1,则代表存在i这个数。举例来说:

给定一个byte,也就是8个bit。如果某组整数可以通过位图表示为 01010000,此时从左往右第5个和7个bit是1,所以这个位向量代表就是{5, 7} 这样一个集合。

书中通过额外提供了部分内存,得到 1 0 7 10^7 107 个bit的内存(大约1.25MB),所以此时利用位向量可以在内存中保存全部的输入数据。

课后习题

2. 使用位运算实现位向量


const int BIT_PER_WORD = 32;  //bits of int, depends on machine
const int SHIFT = 5; // 2^5 = 32
const int MASK = 0x1F; // b'11111 = 10'31

class BitVector{
public:
    BitVector(int ElementNumber){
        this->N = ElementNumber;
        this->intNumber = (N-1)/BIT_PER_WORD + 1;
        this->bit_vec = new int[intNumber];
    }
    ~BitVector(){
        delete [] this->bit_vec;
    }
    void clear(){
        for(int i = 0; i < this->intNumber; ++i){
            this->bit_vec[i] = 0;
        }
    }
    bool set(int i){
    /* 1. 如果要set为1的bit位已经是1的话,返回 false。
          因为任务中默认不会有重复,所以没有检测重复的情况。
       2. i/BIT_PER_WORD = i>>SHIFT = j
            代表set操作发生在第j个int上,即this->bit_vec[j]
       3. i%BIT_PER_WORD = i&MASK = j
            代表set操作会修改某个int的第j个bit */
        this->bit_vec[i>>SHIFT] |= 1<<(i&MASK);
        return true;
    }
    bool contain(int i){
        /* 判断i是否存在 */
        return (this->bit_vec[i>>SHIFT]) & (1<<(i&MASK));
    }
private:
    int * bit_vec = NULL; // allocate space for bit vector
    int N;                // element number
    int intNumber;        // total int number allocate for bit vector
};

版权声明:本文为 DouMiaoO_Oo 原创文章,未经博主允许不得转载!

参考文献

编程珠玑 第二版 修订版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值