读书笔记--编程珠玑II

学化学的应该都知道chemdraw,这是一款专门绘制化学结构的软件,什么苯环、双键各种word难以搞定的分子式,你可以轻松的用chemdraw完成,可以称得上化学工作者居家旅行必备的良药。其实早在1987年的时候,贝尔实验室的大牛Brian Kernighan(就是K&R教你写C语言中的K)和人一起设计了Chem语言,到现在还能用,似乎在书籍排版上比chemdraw的效果更好。说了这么多,咱不是给Chem做广告,而是为了引出它的另一位创作人Jon Bebtley,也是本文即将谈到的《编程珠玑II》——非常受程序员欢迎的系列书籍的作者。

《编程珠玑II》是一部短文集,涵盖了程序员操纵程序的技术、程序员取舍的技巧、输入和输出设计以及算法示例。

开头提到的Chem语言是Pic语言的预处理器,通过作者在书中第9章讨论的Pic语言一例,我们能够明白按照语言的特性对程序进行检查,可以帮我们更好地理解所使用的语言工具,并能教会我们为以后的程序设计更优雅的界面。

编程语言设计原则

  • 设计目标:设计语言之前,要认真研究你试图解决的问题。
  • 简单性:让你的语言尽可能地简单。规模小的语言便于实现者设计、创建、写文档和维护、也便于使用者学习和使用。
  • 基本的抽象:常见的程序设计语言是基于冯?诺伊曼计算机的视角进行创建的,其指令只对小块的数据进行操作。基本对象就是程序的抽象数据类型,而操作就是关键的字程序。
  • 语言的结构:表达式的自然性和实现的方便性需要做出权衡,缩进和注释都是必需的。
  • 正交性:问题中不相关的特性在语言中也不相关;
  • 设计语言的准绳:
    • 一般性:一种操作用于多种目的;
    • 简约性:去掉不需要的操作;
    • 完全性:所设计的语言能描述所有感兴趣的对象吗? 
    • 相似性:让语言尽可能有启发性;
    • 可扩展性:确定语言可以进一步发展;
    • 开放性:允许用户“溜走”以使用其它工具;
  • 设计过程:在实现语言之前,通过描述语言中大量的对象来测试你的设计,当语言完成并付诸实用后,还要反复进行新的设计已根据客户的需要加入新特性。
  • 对编译器生成的深刻见解:尽可能地从后端的处理过程中将前端的语言分析分离出来,这样处理器的创建更容易,也更容易兼容到系统或新的语言用途中。

文档设计和编程有诸多相似之处,书中第10章通过几副不断完善的表格、插图,穿插着介绍了文档设计的原则。

文档设计

文档生成和编程有很多共同之处,两者都要“创造对他人有用的东西”和“必须出色的完成论文”,两者最大的共同点是都能让人尽享“创造的乐趣”。

文档设计需要创意。如果所有人着装相同,所有车的车型和颜色也一样,那么这个世界是多么地乏味。一个所有风格看上去差不多相同的文档库也是一样。综合考虑文档的许多属性,才能得到最佳的计效果。

但是要当心创意过度,好的排版并不能弥补文章本质上的缺陷,如拼写错误、语法不当、结构性差以及内容空洞等。好的文档风格就像好的编程风格和好的写作风格一样,是无形的。内容是文档的首要目的,文档风格只是达到这一目的的辅助手段。

合适的方式表达思想,参考勾股定理:”直角三角形的斜边地平方等于两直角边的平方和“,可以用下图和等式a²+b²=c²来表达这一信息

也可以用欧几里得表示法

根据计算机摩尔定律,我们可以存储越来越多的数据,并对其进行越来越多的处理,可是在系统执行了大量计算后,我们又该如何从海量数据中得出大趋势呢?

图形化输出

你如何概述拿破仑1812年在俄罗斯战役中的挫败?很多程序猿会试着打印出几十厘米数据(每天的人员数量、军饷、驻军地点),法国工程师Charles Joseph Minard在1861年用一种不同的方式来描述这个问题:只用一张简单的图来总结该战役。有人评价这可能是有史以来最好的统计学绘图。

本图给出了与地图上的城市、河流等背景相关联的六个变量:驻军地点(经纬度)、军队规模(和带宽成比例)、行军方向、气温以及日期,从中可以看到一支军队的毁灭与一个帝国走向灭亡的起点。

最后来几个书中提到的算法:

随机取样

许多随机取样要求随机样本中没有重复元素,以下伪代码为算法S,这个算法把结构保存在集合S中,如果S的实现正确,并且RandInt产生随机整数,那么这个算法生成随机样本,每个M元子集的概率都是

initialize set S to empty

Size := 0

while Size < M do

     T := randInt(1,N)

     if T is not in s then

         insert T in S

         Size := Size + 1

算法S有很多优点:正确、相当高效、非常简洁,似乎好的不能再改进了。不幸的是Bob Floyd发现,当M=N=100时明显存在一个缺陷。当Size=99时,集合S缺一个整数。算法闭着眼睛乱猜整数,直到偶然碰上正确的那个为止,这平均需要猜100个随机数。这个分析假设随机数发生器是真正随机的。对于某些非随机排列,这个算法甚至不会停止。Floyd开始寻找一个算法,对于S中每个随机数只恰好调用一次RandInt。

initialize set S to empty
for J := N - M + 1 to N do
    T := randInt(1,J)
    if T is not in S then
         insert T in S
       else
         insert J in s

牛顿迭代法计算K维空间两点距离

T := abs(A[1] - B[1])

Max := T: Sum := T*T

for J := 2 to K do

       T  := 2 to K do

       if T > Max then Max : = T

       Sum := Sum + T*T

if Sum = 0.0 then return 0.0

Eps = 1.0e-7

Z := Max

loop

      NewZ := 0.5 * (Z + Sum/Z)

      if abs(NewZ - Z) <= Eps*NewZ then break

      Z := NewZ

return NewZ

时间: 2024-11-02 09:36:15

读书笔记--编程珠玑II的相关文章

[读书笔记·编程珠玑] 数组移位(待填坑)

要求:已知一个一维数组 arr ,现在要求将它向左旋转n个位置. 方法一: 假设允许开辟一个临时空间,那么问题就变得简单了,可以开辟一个跟arr长度相同的空间,然后隔n个位置不断添加元素即可,思路比较简单,下面是代码实现: void RotateLeft1(vector<int> &arr, const int step) { vector<int> ret; int sz = arr.size(); ret.resize(sz); for (int i = 0; i &l

编程珠玑番外篇

1.Plan 9 的八卦 在 Windows 下喜欢用 FTP 的同学抱怨 Linux 下面没有如 LeapFTP 那样的方便的工具. 在苹果下面用惯了 Cyberduck 的同学可能也会抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻烦的事情. 其实一点都不麻烦, 因为在 LINUX 系统上压根就不需要用 FTP. 为什么呢? 因为一行简单的配置之后, 你就可以像使用本机文件一样使用远程的任何文件. 无论是想编辑, 查看还是删除重命名, 都和本机文件一样的用. 这么神奇的功能到底如何

大话数据结构读书笔记

大话数据结构读书笔记 编程基础: 数据结构 算法 1 线性表 //顺序储存结构的结构代码: #define MAXSIZE 20//储存空间的起始分配量 typedef int ElemType;//ElemType类型根据实际类型而定,这里假设是int typedef struct{ ElemType data[MAXSIZE];//数组储存元素,最大值为MAXSIZE int length;/线性表当前长度: }SqList; //顺序存储结构需要三个属性: //1存储空间的起始位置:数组d

读书笔记第一周《编程珠玑》

--<编程珠玑>读后感 因为时间原因,现在只读了书的前四章以及关于代码优化的第九章,虽然感觉因为语言文化的差异或者翻译的问题,行文感觉十分别扭,但是仍是收益良多. 开篇提出的问题的解决方式令人印象深刻,巧妙地利用位图的方式解决了一个电话号码的排序问题,并且大大降低了时间与空间复杂度.其实引人深思的不仅是这样一种算法,而是文中告诫大家,我们不应当看到问题的第一时间就在脑中搜索我们学习的相关知识,这样很容易搜寻到不是最适合此问题的解决办法.作者在获取更多关于问题的信息后,得到了这个问题数据独有的特

第8周读书笔记-读《编程珠玑》有感

读<编程珠玑>有感 <编程珠玑>(后文简称<珠玑>)在序章中就开宗明义地提出了两个问题:一个是如何对实际问题进行抽象,找出问题的独特性质.二是一个富有意思的小题目:"如何在1MB内存内对0~10^7内若干元素组成的集合内的整数进行排序(10s内)".一开始我想到的是归并排序,但是书中提出可以利用位图的位向量,不用考虑任何排序算法,只需要遍历两次即可,忽然就有茅塞顿开之感,从这个简单的例子中就可以对一些思想窥见一斑:位图数据结构.简单的设计.时间-空间

《Java编程那点事儿》读书笔记(七)——多线程

1.继承Thread类 通过编写新的类继承Thread类可以实现多线程,其中线程的代码必须书写在run方法内部或者在run方法内部进行调用. public class NewThread extends Thread { private int ThreadNum; public NewThread(int ThreadNum){ this.ThreadNum = ThreadNum; } public void run(){ try{ for(int i = 0;i < 10;i ++){ T

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)

《C#高级编程》读书笔记

<C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) short System.Int16 16位有符号的整数 -32 768~32 767(−215−215~215−1215−1) int System.Int32 32位有符号的整数 -2 147 483 648~2 147 483 647(−231−231~231−1231−1) long System.Int

《Android编程权威指南》-读书笔记(三)Git初探

<Android编程权威指南>-读书笔记(三)Git初探 版本控制-Git 为什么要使用版本控制 什么是版本控制?我为什么要关心它呢?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.在本书所展示的例子中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,你可以对任何类型的文件进行版本控制. 如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能).采用版本控制系统(VCS)是个明智的选择.有了它你就