第一章

  1. 如果不缺内存,如何使用一个具有库的语言来实现一种排序算法以表示和排序集合。
    compare方法:
int compare(void const *a, void const *b){
    return *(int *)a- *(int *)b;
}

实现:

int n;
    scanf("%d",&n);
    int c[n];
    for (int i = 0; i < n; i ++) {
        scanf("%d",&c[i]);
        qsort(c, n, sizeof(int), compare);
    }
    for (int i = 0; i < n; i ++) {
        printf("%d",c[i]);
    }
  1. 如何使用为逻辑运算(如与、或、移位)来实现位向量。
    宏定义
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
#define K 1000000

全局变量声明:

int a[1 + N/BITSPERWORD];

赋值函数:

//i>>SHIFT i右移5位,作为a的下标
//i & MASK int32位,确定在哪一位 
void set(int i){
    a[i>>SHIFT] |= (1<<(i & MASK));
}

清空函数:

//~(1<<(i & MASK)) 实际对i取反 &= 操作之后结果为00000
void clr(int i){
    a[i >> SHIFT] &= ~(1<<(i & MASK));
}

校验函数:

int test(int i){
    return a[i >> SHIFT] & (1 << (i & MASK));
}
  1. 运行效率是设计目标的重要组成部分,所得到的程序需要足够高效。在你自己的系统上实现位图排序并度量其时间。该时间与系统排序的运行时间以及习题1排序运行的时间相比如何?假设n为10000000,并输入文件包含1000000个整数。
    使用习题2的答案来实现排序算法。
for (int i = 0; i < N; i ++) {
        clr(i);
        while (scanf("%d",&i) != EOF) {
            set(i);
        }
    }
    for (int i = 0; i < N; i ++) {
        if (test(i)) {
            printf("%d\n",i);
        }
    }
  1. 如果认真考虑了习题3,你将会面对一个生成小于n且没有重复的k个整数的问题。最简单的方法就是使用前k个正整数。这个极端的数据集合将不会明显地改变位图方法的运行时间,但可能会扭曲系统排序的运行时间。如何生成位于0到n-1之间的k个不同的随机栓恤的随机整数?尽量使你的程序简单且高效。
    生成随机数的函数
int randint(int l,int u){
    int temp;
    srand((unsigned)time(NULL));
    temp = floor(l + (1.0*rand()/RAND_MAX)*(u - l + 1 ));
    return temp;
}

交换函数:

void swap(int *a,int *b){
    int t;
    t = *a;
    *a = *b;
    *b = t;
}

声明全局变量narray

int narray[N];

实现:

//对narray赋值
for (int i = 0 ; i < N; i ++) {
        narray[i] = i;
    }
    //声明karray
    int karray[K];
    //dui对karray赋值
    for (int i = 0; i < K; i ++) {
    //随机打乱narray顺序并对karray赋值
    swap(&narray[i], &narray[randint(i, N - 1)]);
        karray[i] = narray[i];
    }
    //清除
    for (int i = 0; i < N; i ++) {
        clr(i);
    }
    //赋值
    for (int i = 0; i < K; i ++) {
        set(karray[i]);
    }
    //校验和输出
    for (int i = 0; i < N; i ++) {
        if (test(i)) {
            printf("%d\n",i);
        }
    }
  1. 那个程序员说他有1MB 可用存储空间,但是我们概要描述的代码需要1.25MB的空间。他可以不费力气的索取到额外的空间。如果1MB的空间是严格的边界,你会推荐如何处理?你的算法的运行时间又是多少?
    使用位图表示1000万个数需要1000万个位,或者说125万字节考虑到没有数字1和0开头的电话号码,我们可以将内存需求降低为100万字节。另外一种做法是采用两趟算法,首先用5000000/8=625000个字节的存储空间来排序0-4999999之间的整数,然后在第二趟排序5000000-9999999的整数。k趟算法可以在kn的时间开销和n/k的空间开销内完成对最多n个小于n的无重复正整数的排序。
  2. 如果那个程序员说的不是每个文件最多出现1次,而是每个整数最多出现10次,你又如何建议他?你的解决方案如何随着可用存储空间的总量的变化而变化?
    如果每个整数最多出现10次,那我们可以使用4位的半字节来统计它出现的次数。利用习题5的答案,我们可以10000000/2个字节在1趟内完成对整个文件的排序,或者使用10000000/2k个字节在k趟内完成对整个文件的排序。

宏定义:

#define BITSPERWORD 16
#define SHIFT 3
#define MASK 0x07
#define N 10000000
#define K 1000000

函数:

void set(int i){
    a[i>>SHIFT] += (1<<(4 *(i & MASK)));
}

void clr(int i){
    a[i >> SHIFT] &= ~(0x0F<<(4*(i & MASK)));
}

int test(int i){
    return (a[i>>SHIFT] & (0x0F<<(4 *(i&MASK))))>>4*(i&MASK);
}

代码测试:

int number[5] = {13,9,13,11,13};
    for (int i = 0; i < 5; i ++) {
        clr(number[i]);
    }
    
    for (int i = 0; i < 5; i ++) {
        set(number[i]);
    }

    printf("number==%d\n",test(13));
  1. 本书1.4节中描述的程序存在一些缺陷。首先是假定在输入中没有出现两次的整数。如果某个数出现超过一次的话,会发生什么?在这种情况下,如何修改程序来调用错误处理函数?当输入整数小于0或大于等于n时,又会发生什么?如果某个输入不是数值又如何?在这种情况下,程序应该如何处理?程序还应该包含哪些明智的检查?描述一些用以测试程序的小型数据集合,并说明如何正确处理上述以及其他的不良情况。
    可能我想的这些都是一些很浅显的想法,但无论怎样先记录下来吧。
    如果整数超出一次的话,在保存的时候进行记录。超出一次的后果第一次存储的数据会被第二次的替换,排序总数少一个。
    当输入的整数小于零或大于n时,排序相当于对n-1个整数排序。如果输入的不是数值有可能会发生崩溃的情况比如输入的是char类型字符,也有可能发生和输入大于n小于0一样的情况。这样的情况下需要对输入的信息进行判断,当信息不准确的时候提示重新输入或者结束当前程序。
    就先写下了这么多。
  2. 当那个程序员解决gai该问题的时候,美国所有免费电话的区号都是800。现在免费的区号包括800、877、和888,而且还在增多。如果在1MB空间内完成对所有这些免费电话的排序?如何将免费电话号码存储在一个集合中,要求可以实现非常快速的查找以判定一个给定的免费电话号码是否可用或者已经存在?
    随机数的生成出现了一些问题,有时间再回来解决。
  3. 使用更多的空间来换取更少的运行时间存在一个问题:初始化空间本身需要消耗大量的时间。艘名如何设计一种技术,在第一次访问向量时将其初始化为0。你的方案应该使用常量时间进行初始化和向量访问,使用的额外空间正比于向量的大小。因为该方法通过进一步增加空间来减少初始化的时间,所以仅在空间很廉价、时间很宝贵且响亮很稀疏的情况下才考虑使用。
    借助于两个额外的向量from、to和一个整数top,我们就可以使用表示来初始化向量data[0..n-1]。如果元素data[i]已经初始化,那么from[i]<top并且to[from[i]] = i。因此,from是一个简单的标识,to和top一起确保了from中不会被写入内存里的随机内容。
    代码展示:(不确定正确)
int nameArray[100000];
    int from[100];
    int to[100];
    int top = 2;
    from[80] = top;
    to[from[80]] = 80;
    nameArray[80] = 33;
    top ++;
  1. 在成本低廉的隔日送达时代之前,商店允许顾客通过电话订购商品,并在几天后上门自取。尚待你的数据库使用客户的电话号码作为其检索的主关键字(客户知道他们自己的电话号码,而且这些关键字几乎都是唯一的)。你如何组织商店的数据库,以允许高效的插入和检索操作?
    商店将纸质的表格放在10*10的箱数组中,使用客户电话号码的最后两位作为散列索引。当客户打电话下订单时,将订单放到适当的箱中当客户来取商品时,销售人员顺序搜索对应箱中的订单-这就是经典的“用顺序搜索来解决冲突中的开放散列”。电话号码的最后两位非常接近随机,因此是非常理想的散列函数,而最前面的两位数字很不理想。
  2. 载人航天的先驱们很快就意识到了需要在外太空的极端环境下实现顺利的书写。民间盛传美国航天宇航局话费100万美元研发出来了一种特殊的钢笔来解决这个问题。那么,前苏联又会如何解决相同的问题呢?
    民间盛传的美国宇航局话费100万美元研发出来了这种钢笔的信息是错误的。这种钢笔确实是由美国的一个商人自费研发出来的,后卖给了美国宇航局使用。苏联据说也在使用这种钢笔。这个故事可以告诉我们三个道理(1):不要被事物的表象迷惑。针对每一件事情而言,你都需要彻彻底底的融入进去知道每一步的每一个细节,知道每一步的每一个原因。没有特别小的事情,很多时候一件事情涉及到了很多知识和智慧。再回头可能不是我们当初想象的那么简单。(2)对一件事情换一个思路可能会有不同的结果。更多的时候面对一件事情最重要的不是立即去做,而是要好好思考一下怎么去做。(3)无论做什么都要有自己的看法,不要被别人带走了。对对的事情坚持和赞扬,对错的事情避
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,658评论 0 33
  • 《速度与激情8》告诉我们:一个人干不过一个团队,一个团队干不过一个系统,一个系统干不过一个趋势! 『团队+系统+趋...
    享杰同学阅读 673评论 0 0
  • 25岁的你,大学毕业不到五年。 相信在大学时,很多人都会设想自己的未来是什么样的。可能有的人想当公务员,想掌握权力...
    当代坐家阅读 247评论 1 1