《编程珠玑》读书笔记——第一章.开篇

问题描述

一、输入及约束:在1MB内存中花费10s的时间对10^7个均小于10^7的不重复的数。
二、输出:按升序输出。
(p.s:1MB总共有 1028*1024*8=838,8608个可用位。)

分析:

1. 基于磁盘的归并排序(虽然代码长度减少了,但是运行时间很长)
2.每个号码用7个字节储存,那么1MB内大约可存143 000个号码。若每个号码使用32位整数来存,1MB内能存约250 000个号码。那么10^7个数据可分(10^7/2.5x10^5=40)约40次排序完成排序操作。在内存中采用40趟快速排序。(还是耗时间,而且麻烦)
3.位图法(bitmap):使用一个长10^7位长的字符串来表示每个数。比如集合{0,2,5}就可表示为[101001](即存在该数该位位1否则为0)。然后按顺序输出该数即可。
(p.s:按照该方法内存约为1.25MB,如果要严格限制为1MB,那么①可采用方法二的思想,将一趟遍历其拆分为两趟②将数据中稀疏位去除。)

Exercises:

1.如果不缺内存,使用一个具有库的语言实现排序算法
#include <iostream>
#include <algorithm>
int main()
{
    // sort(); 自带库函数,不解释
    return 0;
}

// 手写快排= =
int Partition(int *array, int left, int right)
{
    int priot = array[left];
    int first = left;
    int last = right;
    while(first < last)
    {
        while(first < last && array[last] >= priot)
        {
            last--;
        }
        Swap(&array[first], &array[last]);
        while(first < last && array[first] <= priot)
        {
            first++;
        }
        Swap(&array[first], &array[last]);
    }
    return first;
}

void QuickSort(int *array, int first, int last)
{
    if(array == NULL)
    {
        return;
    }
    if(first < last)
    {
        int priot = Partition(array, first, last);
        QuickSort(array, first, priot - 1);
        QuickSort(array, priot + 1, last);
    }
}
2.如何使用位逻辑运算来实现位向量
#include <cstdio>
#define BITSTEPWORD 32 //表示一个整形含有32位
#define SHIFT 5 //单次位移量,左移相当于乘32
#define MASK 0x1F //16进制下的31 掩码
#define N 100000000

int array[1 + N / BITSTEPWORD]; // 使用整形数组模拟定义10^7个位的数组

// 置位函数——用"|"操作符,i&MASK相当于mod操作
void set(int i) 
{
    array[i >> SHIFT] |= (1 << (i & MASK) );
}

// 清除位操作,用&~操作符
void clr(int i)
{
    array[i >> SHIFT] &= ~(1 << (i & MASK) );
}

//  测试位操作用&操作符
int test(int i)
{
    return array[i >> SHIFT] & (1 << (i & MASK) );
}

int main()
{
    for (int i = 0; i < 100; ++i)
        set(i*2);
    for (int i = 0; i < 200; ++i)
        printf("%d\n",test(i) ? 1 : 0 );
    return 0;
}
具体说明
① i >> SHIFT :将i右移5位,相当于i除以32,因为int为32位,除以32表示在第几个成员中;举个栗子:如果i为34,则结果为1,说明在array[1]中。
② 1 << (i & MASK) :用掩码留下i的低5位再左移1位,相当于除以32所得余数再左移动1位,因为第一位为0,所以都需要移动1位,结果中1所在位表示i在该数组成员中的第几位上;接着上个栗子,i为34,则i & MASK为2,二进制为10,再向左移动一位为100,说明从0开始第2位是1。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值