一,概述

主要讲解如何保证编程的正确性。在程序中加入断言(assert(断言内容) //如果错误,则终止程序。否则正常执行)。

typdef   //声明自定义类型

typedef int size; //声明int 型整数的别名

size array[4];

typedef struct tagNode { char *pItem;  pNode *pNext; } *pNode;

测试结构题大小的程序

#include "stdio.h" typedef struct tagNode { char *pItem; //32位 struct tagNode *pNext;//32位 } *pNode; int main() { printf("%d\n",sizeof(struct tagNode)); return 0; }

二,习题

5)测试、断言优化过程

for (i = 0; i < n - 1; ++i) assert(a[i] < a[i+1]);

如何利用二分的性质来进行处理还是一个问题。

一种办法是:

int bs(int *a, int b, int e, int v) { int *begin = a + b, *end = a + e, *mid; if (!a || b >= e) return -1; while (begin < end) { mid = begin + ((end - begin) >> 1); assert(*begin <= *mid && *mid <= *end); if (*mid > v) end = mid; else if (*mid < v) begin = mid + 1; else return mid - a; } return -1; }
    但是这个方法需要多次使用才能检测出来,也就是可能在查找某两个数的时候不会报错,可能在查找别的几个数的时候就报错了。很多时候,这不是一种好选择。

根据第五题的题意,可以写如下代码来减少每次检测的量。

int bs(int *a, int b, int e, int v) { int *begin = a + b, *end = a + e, *mid, i = b; static int *record = 0; if (!a || b >= e) return -1; if (!record || record != a) { while (i < e && a[i] < a[i+1]) ++i; assert(i == e); } while (begin < end) { mid = begin + ((end - begin) >> 1); assert(*begin <= *mid && *mid <= *end); if (*mid > v) end = mid; else if (*mid < v) begin = mid + 1; else return mid - a; } return -1; }

加一个static变量来记录这个数组是否经过检测,来决定以后的检测还需要进行。

当然对于多个数组的检测,可以利用hash来处理,因为一般来说,数组的下标地址都是不一样的。

[html] view plaincopy
  1. for (i = 0; i < n - 1; ++i)
  2. assert(a[i] < a[i+1]);

如何利用二分的性质来进行处理还是一个问题。

一种办法是:

[cpp] view plaincopy
  1. int bs(int *a, int b, int e, int v)
  2. {
  3. int *begin = a + b, *end = a + e, *mid;
  4. if (!a || b >= e) return -1;
  5. while (begin < end)
  6. {
  7. mid = begin + ((end - begin) >> 1);
  8. assert(*begin <= *mid && *mid <= *end);
  9. if (*mid > v) end = mid;
  10. else if (*mid < v) begin = mid + 1;
  11. else return mid - a;
  12. }
  13. return -1;
  14. }

但是这个方法需要多次使用才能检测出来,也就是可能在查找某两个数的时候不会报错,可能在查找别的几个数的时候就报错了。很多时候,这不是一种好选择。

根据第五题的题意,可以写如下代码来减少每次检测的量。

[cpp] view plaincopy
  1. int bs(int *a, int b, int e, int v)
  2. {
  3. int *begin = a + b, *end = a + e, *mid, i = b;
  4. static int *record = 0;
  5. if (!a || b >= e) return -1;
  6. if (!record || record != a)
  7. {
  8. while (i < e && a[i] < a[i+1]) ++i;
  9. assert(i == e);
  10. }
  11. while (begin < end)
  12. {
  13. mid = begin + ((end - begin) >> 1);
  14. assert(*begin <= *mid && *mid <= *end);
  15. if (*mid > v) end = mid;
  16. else if (*mid < v) begin = mid + 1;
  17. else return mid - a;
  18. }
  19. return -1;
  20. }

加一个static变量来记录这个数组是否经过检测,来决定以后的检测还需要进行。

当然对于多个数组的检测,可以利用hash来处理,因为一般来说,数组的下标地址都是不一样的。

9,,serch.c 源程序

#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAXN 1000000 typedef int DataType; DataType x[MAXN]; int n; /* Scaffolding */ int i = -999999; #define assert(v) { if ((v) == 0) printf(" binarysearch bug %d %d\n", i, n); } /* Alg 1: From Programming Pearls, Column 4: raw transliteration */ int binarysearch1(DataType t) { int l, u, m; l = 0; u = n-1; for (;;) { if (l > u) return -1; m = (l + u) / 2; if (x[m] < t) l = m+1; else if (x[m] == t) return m; else /* x[m] > t */ u = m-1; } } /* Alg 2: Make binarysearch1 more c-ish */ int binarysearch2(DataType t) { int l, u, m; l = 0; u = n-1; while (l <= u) { m = (l + u) / 2; if (x[m] < t) l = m+1; else if (x[m] == t) return m; else /* x[m] > t */ u = m-1; } return -1; } /* Alg 3: From PP, Col 8 */ int binarysearch3(DataType t) { int l, u, m; l = -1; u = n; while (l+1 != u) { m = (l + u) / 2; if (x[m] < t) l = m; else u = m; } if (u >= n || x[u] != t) return -1; return u; } /* Alg 4: From PP, Col 9 */ int binarysearch4(DataType t) { int l, p; if (n != 1000) return binarysearch3(t); l = -1; if (x[511] < t) l = 1000 - 512; if (x[l+256] < t) l += 256; if (x[l+128] < t) l += 128; if (x[l+64 ] < t) l += 64; if (x[l+32 ] < t) l += 32; if (x[l+16 ] < t) l += 16; if (x[l+8 ] < t) l += 8; if (x[l+4 ] < t) l += 4; if (x[l+2 ] < t) l += 2; if (x[l+1 ] < t) l += 1; p = l+1; if (p >= n || x[p] != t) return -1; return p; } /* Alg 9: Buggy, from Programming Pearls, Column 5 */ int sorted() { int i; for (i = 0; i < n-1; i++) if (x[i] > x[i+1]) return 0; return 1; } int binarysearch9(DataType t) { int l, u, m; /* int oldsize, size = n+1; */ l = 0; u = n-1; while (l <= u) { /* oldsize = size; size = u - l +1; assert(size < oldsize); */ m = (l + u) / 2; /* printf(" %d %d %d\n", l, m, u); */ if (x[m] < t) l = m; else if (x[m] > t) u = m; else { /* assert(x[m] == t); */ return m; } } /* assert(x[l] > t && x[u] < t); */ return -1; } /* Alg 21: Simple sequential search */ int seqsearch1(DataType t) { int i; for (i = 0; i < n; i++) if (x[i] == t) return i; return -1; } /* Alg 22: Faster sequential search: Sentinel */ int seqsearch2(DataType t) { int i; DataType hold = x[n]; x[n] = t; for (i = 0; ; i++) if (x[i] == t) break; x[n] = hold; if (i == n) return -1; else return i; } /* Alg 23: Faster sequential search: loop unrolling */ int seqsearch3(DataType t) { int i; DataType hold = x[n]; x[n] = t; for (i = 0; ; i+=8) { if (x[i] == t) { break; } if (x[i+1] == t) { i += 1; break; } if (x[i+2] == t) { i += 2; break; } if (x[i+3] == t) { i += 3; break; } if (x[i+4] == t) { i += 4; break; } if (x[i+5] == t) { i += 5; break; } if (x[i+6] == t) { i += 6; break; } if (x[i+7] == t) { i += 7; break; } } x[n] = hold; if (i == n) return -1; else return i; } /* Scaffolding to probe one algorithm */ void probe1() { int i; DataType t; while (scanf("%d %d", &n, &t) != EOF) { for (i = 0; i < n; i++) x[i] = 10*i; printf(" %d\n", binarysearch9(t)); } } /* Torture test one algorithm */ #define s seqsearch3 void test(int maxn) { int i; for (n = 0; n <= maxn; n++) { printf("n=%d\n", n); /* distinct elements (plus one at top) */ for (i = 0; i <= n; i++) x[i] = 10*i; for (i = 0; i < n; i++) { assert(s(10*i) == i); assert(s(10*i - 5) == -1); } assert(s(10*n - 5) == -1); assert(s(10*n) == -1); /* equal elements */ for (i = 0; i < n; i++) x[i] = 10; if (n == 0) { assert(s(10) == -1); } else { assert(0 <= s(10) && s(10) < n); } assert(s(5) == -1); assert(s(15) == -1); } } /* Timing */ int p[MAXN]; void scramble(int n) { int i, j; DataType t; for (i = n-1; i > 0; i--) { j = (RAND_MAX*rand() + rand()) % (i + 1); t = p[i]; p[i] = p[j]; p[j] = t; } } void timedriver() { int i, algnum, numtests, test, start, clicks; while (scanf("%d %d %d", &algnum, &n, &numtests) != EOF) { for (i = 0; i < n; i++) x[i] = i; for (i = 0; i < n; i++) p[i] = i; scramble(n); start = clock(); for (test = 0; test < numtests; test++) { for (i = 0; i < n; i++) { switch (algnum) { case 1: assert(binarysearch1(p[i]) == p[i]); break; case 2: assert(binarysearch2(p[i]) == p[i]); break; case 3: assert(binarysearch3(p[i]) == p[i]); break; case 4: assert(binarysearch4(p[i]) == p[i]); break; case 9: assert(binarysearch9(p[i]) == p[i]); break; case 21: assert(seqsearch1(p[i]) == p[i]); break; case 22: assert(seqsearch2(p[i]) == p[i]); break; case 23: assert(seqsearch3(p[i]) == p[i]); break; } } } clicks = clock() - start; printf("%d\t%d\t%d\t%d\t%g\n", algnum, n, numtests, clicks, 1e9*clicks/((float) CLOCKS_PER_SEC*n*numtests)); } } /* Main */ int main() { /* probe1(); */ /* test(25); */ timedriver(); return 0; }

转载于:https://www.cnblogs.com/JPAORM/archive/2012/05/14/2509997.html

【编程珠玑】第五章 编程小事相关推荐

  1. 编程珠玑第五章习题五——C++实现二分搜索时进行错误检测

    一,概述 主要讲解如何保证编程的正确性.在程序中加入断言(assert(断言内容) //如果错误,则终止程序.否则正常执行). typdef   //声明自定义类型 typedef int size; ...

  2. 【编程珠玑】陪着奶猫看看书--《编程珠玑》第一章

    陪着奶猫看看书–<编程珠玑>第一章 首先说说小奶猫我为什么要读<编程珠玑>这本神作,当年小奶猫刚刚进入大学时候是个纯洁的少年,啥都不懂,要是哪个女生下午在外面问我带身份证没有, ...

  3. Java7并发编程指南——第五章:Fork Join框架

    Java7并发编程指南--第五章:Fork Join框架 @(并发和IO流) Java7并发编程指南第五章Fork Join框架 思维导图 项目代码 思维导图 项目代码 GitHub:Java7Con ...

  4. 浙大PTA-Python题库 编程题第五章(5-1~5-11)题解

    其他各章题解链接如下 浙大PTA-Python题库 编程题第一章(1-1~1-3)题解 https://blog.csdn.net/zimuzi2019/article/details/1070206 ...

  5. core组件进阶(Opencv3编程入门 第五章) 第四节 图像对比度亮度调整

    core组件进阶(Opencv3编程入门 第五章) 第四节 图像对比度亮度调整 #include <opencv2/core/core.hpp> #include <opencv2/ ...

  6. 编程珠玑之第二章习题5

    问题描述: n元一维向量旋转问题数将向量ab变为ba.如何将向量abc变为cba? (这对交换非相邻内存块问题进行了建模) 问题解析: 1.这里需要用到一个重要的性质:CBA=(ArBrCr)r    ...

  7. 编程珠玑第12章习题

    内容来自互联网,做了一些修改 参考: http://blog.csdn.net/tianshuai1111/article/details/7583297 http://blog.csdn.net/t ...

  8. [转]Windows Shell编程 第十五章【来源:http://blog.csdn.net/wangqiulin123456/article/details/7988016】...

    第十五章 SHELL扩展 谈到Windows Shell编程,Shell扩展是最重要的科目之一,绝大多数商业应用的最酷特征的都是通过Shell扩展实现的,而且有许多显著的系统特征实际都是插入了扩展代码 ...

  9. 【Linux命令行与Shell脚本编程】第五章 理解 Shell 父子关系 后台进程 协程

    Linux命令行与Shell脚本编程 第五章 理解 Shell 文章目录 Linux命令行与Shell脚本编程 五,理解 Shell 5.1,shell的类型 5.2,shell的父子关系 5.2.1 ...

  10. c primer plus 第五章编程练习

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 ##1.编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间.使用#define或const创 ...

最新文章

  1. 如何调试程序的后台作业
  2. 揭穿现金贷的真实面目
  3. http和websocket共用同一端口
  4. Python3学习笔记-字符串和字符串操作
  5. 朗文3000词汇表带音标_牛津3000词汇表
  6. 数据字典在mysql中怎么做_如何编写数据字典
  7. python小甲鱼课后作业_小甲鱼python课后习题总结
  8. linux设置字符编码gbk,CentOS修改默认字符编码为GBK
  9. EPLAN之设备编号
  10. Problem C: 点在圆内吗?
  11. 【解决电脑】开机屏幕左键无反应,右键变加载;选择文件夹未响应,卡顿40秒后恢复;新建文件夹正常,删除移动卡顿
  12. MindMapper中各类模板的运用方法
  13. JavaEE学习之jsp编写登陆注册页面
  14. 如何在vue项目中使用Highmaps(vue+Highmaps)
  15. 闪讯客户端 linux,Linux操做系统下链接闪讯的方法(支持有线与无线)
  16. citra 图形设置_Java 编辑PPT SmartArt图形 - E-iceblue
  17. VNC_一款优秀的远程控制工具软件
  18. 常用PHP5函数小全
  19. iOS性能调优利器——Instruments的使用
  20. 基于maxwell的4极6槽 内转子 15000rpm 输出转矩 220mNm 效率89% 120W 外径 48mm

热门文章

  1. [批处理]NetstatFilter快速查找端口被占用问题
  2. mysql如何开启对外连接?
  3. Eclips下运行helloworld,弹出手机模拟器上什么也没有
  4. 《恋上数据结构第1季》二叉树基础、真二叉树、满二叉树、完全二叉树、二叉树的遍历(重点)
  5. 【jQuery笔记Part1】11-jQuery选择器
  6. 一步一坑学android之禁用Appt2(andriod studio3.0)
  7. eclipse 离线安装python开发工具 PyDev
  8. SELinux系列(八)——SELinux默认安全上下文的查询和修改(semanage命令)
  9. java extjs combobox_extjs的combobox的用法
  10. 报表或BI的价值在哪?