SCIP讀書筆記(二)

上一篇中介紹了一門程序設(shè)計(jì)語言必須具備的一些特性,以及Scheme語言的基本語法。這一篇用上一篇提到的平方根的問題來看看一個(gè)問題是如何被逐步分解并解決的。我們首先看下平方根的數(shù)學(xué)定義:

平方根的數(shù)學(xué)定義

上面的數(shù)學(xué)公式描述了一個(gè)數(shù)的平方根所具備的性質(zhì),但并沒有告訴我們應(yīng)該如何去求一個(gè)數(shù)的平方根。這是數(shù)學(xué)公式和計(jì)算機(jī)程序的不同之處。對(duì)于同一個(gè)問題,數(shù)學(xué)公式關(guān)心的是該問題的解所具備的性質(zhì) (what is);而計(jì)算機(jī)程序則關(guān)心應(yīng)該如何去得到問題的解 (how to)。那么到底求一個(gè)數(shù)的平方根呢?我們這里使用牛頓提出的無窮逼近法,這個(gè)算法思路很簡單,先假定我們要求數(shù)y的平方根x

  1. 為x設(shè)定一個(gè)初始值
  2. 檢查x^2是否等于y,若是,則返回x, 否則將x賦值為(x+(x/y))/2
  3. 重復(fù)執(zhí)行第2步直到獲得解。

簡書的markdown對(duì)數(shù)學(xué)公式支持的不好,請(qǐng)見諒。有了上面的描述,我們就可以很快寫出代碼了,下面我就試試使用Scheme語言來實(shí)現(xiàn)。這里還是要扯點(diǎn)題外話,我看SCIP這本書并不是為了學(xué)習(xí)Scheme語言,而是學(xué)習(xí)書中分析問題和將抽象問題的方法,學(xué)習(xí)了這些之后,你會(huì)恍然發(fā)現(xiàn)現(xiàn)在大多數(shù)語言或者工具的一些特性在這本書中都講到了,比如python語言、guava庫、Java8主打的lambda表達(dá)式,stream等。編程語言的發(fā)展有兩條截然不同的路,一條是為了適應(yīng)計(jì)算機(jī)底層硬件或者說計(jì)算機(jī)體系結(jié)構(gòu)發(fā)展起來的,最具代表性的就是C語言;另一條路則是關(guān)心計(jì)算的本質(zhì)(比較抽象,這里僅是個(gè)人觀點(diǎn)),主要的代表就是Lisp語言,而我們這里的談到的Scheme就是Lisp語言的一種變體。但隨著技術(shù)的發(fā)展,這兩種不同類型的語言有點(diǎn)融合的趨勢(shì)。
在寫代碼前,我們首先分析下這個(gè)問題,在上一篇中我們說過,要解決一個(gè)問題時(shí),我們應(yīng)該將問題進(jìn)行分解,得到多個(gè)子問題,當(dāng)子問題解決后,我們將子問題的解組合就得到了原問題的解。通過算法的描述我們可以將原有的問題分解成一些子問題:判斷數(shù)x是不是問題的解;使用算法描述中的方法將x加以改進(jìn),每次對(duì)x的改進(jìn)都能夠更加接近問題的解,這就是無窮逼近。我們用Scheme語言翻譯下就是這樣:

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

這里引入了函數(shù)sqrt-iter,它接收兩個(gè)參數(shù)x和y,x表示對(duì)y的平方根的猜想,通過遞歸調(diào)用(在Scheme語言里十分重要)得到解。在sqrt-iter里又引入了兩個(gè)函數(shù):good-enough?和imporve,對(duì)應(yīng)著我們分析的兩個(gè)子問題。而good-enough?應(yīng)該如何定義的呢?它接收兩個(gè)參數(shù)x和y,判斷x^2是否等于y。這個(gè)問題是一個(gè)比較經(jīng)典的面試題:判斷兩個(gè)浮點(diǎn)數(shù)是否相等。

(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函數(shù)我們可以根據(jù)算法描述得到:

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

這些子問題解決后,原問題就迎刃而解了:

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

這里我們假定任何數(shù)的平方根的初始值為1.0。現(xiàn)在我們?cè)賮砜聪聅qrt函數(shù),我們可以得到下面這張圖:

sqrt函數(shù)分解圖

我們?cè)谔幚碓瓎栴}(sqrt)的時(shí)候,我們只需關(guān)心抽象的各個(gè)子問題,而每個(gè)子問題又可以分解為更多的子問題,各個(gè)子問題可以看做是一個(gè)個(gè)的黑匣子,我們無需關(guān)心起內(nèi)部實(shí)現(xiàn)的細(xì)節(jié),我們關(guān)心其提供的功能就夠了。其實(shí)任何的程序設(shè)計(jì)都可以通過這種手段去將問題逐步分解,這里的分解還需要注意一個(gè)問題,就是每個(gè)被分解后的子問題應(yīng)該遵循單一職責(zé)的原理,只有這樣,解決該子問題的方法才有可能被其他的模塊進(jìn)行復(fù)用。就像搭積木的例子里,我們應(yīng)該去組合一些通用形狀的積木。
好了,這一篇就簡單介紹了分析問題的方法。有疑問?請(qǐng)留言。另外課后的作業(yè)有一道題是之前搜狗公司的面試題,讀者可以思考下:

有inc函數(shù)和dec函數(shù),inc函數(shù)的作用是將輸入的參數(shù)加1后返回,dec函數(shù)的作用是將輸入的參數(shù)減1后返回,利用inc函數(shù)和dec函數(shù)定義加法函數(shù)。
(define (+ a b) (...))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,115評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,234評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,621評(píng)論 1 326
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,822評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,380評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,128評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,319評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,548評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評(píng)論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,048評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,285評(píng)論 2 376

推薦閱讀更多精彩內(nèi)容