SCIP读书笔记(二)

上一篇中介绍了一门程序设计语言必须具备的一些特性,以及Scheme语言的基本语法。这一篇用上一篇提到的平方根的问题来看看一个问题是如何被逐步分解并解决的。我们首先看下平方根的数学定义:

平方根的数学定义

上面的数学公式描述了一个数的平方根所具备的性质,但并没有告诉我们应该如何去求一个数的平方根。这是数学公式和计算机程序的不同之处。对于同一个问题,数学公式关心的是该问题的解所具备的性质 (what is);而计算机程序则关心应该如何去得到问题的解 (how to)。那么到底求一个数的平方根呢?我们这里使用牛顿提出的无穷逼近法,这个算法思路很简单,先假定我们要求数y的平方根x

  1. 为x设定一个初始值
  2. 检查x^2是否等于y,若是,则返回x, 否则将x赋值为(x+(x/y))/2
  3. 重复执行第2步直到获得解。

简书的markdown对数学公式支持的不好,请见谅。有了上面的描述,我们就可以很快写出代码了,下面我就试试使用Scheme语言来实现。这里还是要扯点题外话,我看SCIP这本书并不是为了学习Scheme语言,而是学习书中分析问题和将抽象问题的方法,学习了这些之后,你会恍然发现现在大多数语言或者工具的一些特性在这本书中都讲到了,比如python语言、guava库、Java8主打的lambda表达式,stream等。编程语言的发展有两条截然不同的路,一条是为了适应计算机底层硬件或者说计算机体系结构发展起来的,最具代表性的就是C语言;另一条路则是关心计算的本质(比较抽象,这里仅是个人观点),主要的代表就是Lisp语言,而我们这里的谈到的Scheme就是Lisp语言的一种变体。但随着技术的发展,这两种不同类型的语言有点融合的趋势。
在写代码前,我们首先分析下这个问题,在上一篇中我们说过,要解决一个问题时,我们应该将问题进行分解,得到多个子问题,当子问题解决后,我们将子问题的解组合就得到了原问题的解。通过算法的描述我们可以将原有的问题分解成一些子问题:判断数x是不是问题的解;使用算法描述中的方法将x加以改进,每次对x的改进都能够更加接近问题的解,这就是无穷逼近。我们用Scheme语言翻译下就是这样:

(define (sqrt-iter x y)
    (if (good-enough? x y)
         x
         (sqrt-iter (imporve x y) y)))

这里引入了函数sqrt-iter,它接收两个参数x和y,x表示对y的平方根的猜想,通过递归调用(在Scheme语言里十分重要)得到解。在sqrt-iter里又引入了两个函数:good-enough?和imporve,对应着我们分析的两个子问题。而good-enough?应该如何定义的呢?它接收两个参数x和y,判断x^2是否等于y。这个问题是一个比较经典的面试题:判断两个浮点数是否相等。

(define (good-enough? x y)
    (< (abs (- (square x) y)) 0.001))
(define (square x) (* x x))
(define (abs x) 
    (if (> x 0) x (- x)))

improve函数我们可以根据算法描述得到:

(define (improve x y) 
    (average x (/ x y)))
(define (average x y)
    (/ (+ x y) 2))

这些子问题解决后,原问题就迎刃而解了:

(define (sqrt x)
    (sqrt-iter 1.0 x))

这里我们假定任何数的平方根的初始值为1.0。现在我们再来看下sqrt函数,我们可以得到下面这张图:

sqrt函数分解图

我们在处理原问题(sqrt)的时候,我们只需关心抽象的各个子问题,而每个子问题又可以分解为更多的子问题,各个子问题可以看做是一个个的黑匣子,我们无需关心起内部实现的细节,我们关心其提供的功能就够了。其实任何的程序设计都可以通过这种手段去将问题逐步分解,这里的分解还需要注意一个问题,就是每个被分解后的子问题应该遵循单一职责的原理,只有这样,解决该子问题的方法才有可能被其他的模块进行复用。就像搭积木的例子里,我们应该去组合一些通用形状的积木。
好了,这一篇就简单介绍了分析问题的方法。有疑问?请留言。另外课后的作业有一道题是之前搜狗公司的面试题,读者可以思考下:

有inc函数和dec函数,inc函数的作用是将输入的参数加1后返回,dec函数的作用是将输入的参数减1后返回,利用inc函数和dec函数定义加法函数。
(define (+ a b) (...))

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容