第一回 哥倫布水杯戲權貴,阿蘭煮酒論程式設計

大大老狼發表於2014-10-13

2.1第一回 哥倫布水杯戲權貴,阿蘭煮酒論程式設計

第一回介紹的故事是關於航海家哥倫布的,本質上只說了一件事:什麼是程式?

程式是怎麼回事,和哥倫布又有什麼關係呢?說簡單很簡單,用兩個杯子比劃一下就有了。故事還要從很久以前說起,1492年10月12日,哥倫布(Christopher Columbus)發現了新大陸——美洲大陸,他是發現美洲的第一人;同樣的,在電腦世界中也有許多第一,那問一個最簡單的問題:第一個程式是誰發明的呢?對於這個問題,現在很難考證。但經阿蘭論證,程式和哥倫布有一定的關係,不信,請接著看。

在很懂電腦和不很懂電腦的許多人中,有人會問:“程式設計,程式設計,到底什麼是‘程’呢?”說來說去,對於初學者,“程式”這一詞才是最難破解的。其實程式意思非常簡單,就是步驟。當我們能明白“程式”這兩個字的意思的時候,距明白程式設計就不遠了。而哥倫布將給我們上很好的一課。

2.1.1 P1:哥倫布水杯問題

哥倫布何許人也?他正好逝世了五百年,他生活在1451到1506年,是西班牙的著名航海家,是地理大發現的先驅,尤其以發現美洲大陸而名垂青史。

enter image description here

圖 2.1.1新大陸的發現者哥倫布

哥倫布發現了新大陸後,在皇室為他舉行的慶功宴中,有許多權貴對他不服,其中有一位大臣不服氣地說:“任何人坐在船上航行,都能到達大西洋的對岸,有什麼希奇,值得大家這樣大驚小怪!”有幾個大臣也在一旁附和。

哥倫布聽到後一言不發,朋友們都為他著急,埋怨他為什麼不辯解呢。

過了一會兒,哥倫布叫僕人從廚房拿來兩個同樣大小的茶杯,它們盛有滿滿的兩杯水,一個杯中是茶水,另一個杯中也是水,只不過是鹽水,他提出的問題是,如何將兩杯水交換?許多人嘗試,包括當時西班牙最著名的雜技師也想把這兩杯水倒過來,卻都失敗了。下面輪到哥倫布了,朋友們為哥倫布捏了一把汗。哥倫布怎麼辦呢?

這時只見哥倫布又拿來一個杯子,……

滿桌的王公大臣譁然,都叫著這算什麼遊戲,三歲小孩也會做啊! 我們的問題是:大家為什麼譁然,而哥倫布究竟是怎樣交換的呢?

2.1.2 哥倫布水杯問題解析

人們糾結於現有的兩個杯子,如何用這兩個杯子交換過來?這好象是潛臺詞,但直接交換顯然是不行的,不可能將第一個杯的水直接倒在第二個杯中,那不是我們能做到的結果,但我們的思路卻往往侷限在這之上。那麼請思考,如果用直接交換,除非我們會變戲法,象手裡拿著三個帽子在頭上和兩手間輪換,但不可能滴水不漏地將第一個杯子中的水直接倒在第二個杯中。 僅僅只有兩個杯子在地球上是幾乎不可能完成的,哥倫布的驚人之舉就在於拿來了第三個杯子!利用第三隻杯子,我們的工作就簡單了,可以這麼做(如下圖示,用a,b,c表示三隻杯子):

1. 將b杯中的茶水倒入空杯c中,使b杯先空出來;

enter image description here

圖2.1.2 水杯交換

2.將a杯中的鹽水倒入空出來的b杯中,現在a杯空出來了;

3.將c杯中的茶水倒入a杯中。交換完成。

上面事實上就是程式,我們在生活中解決問題的步驟,將這種步驟換上具體的電腦語言,那就成了電腦“程式”了。 上面是我們所遇到的最簡單的一個可以作為程式的例子。1、2、3的次序是不可以交換的。這個例子用計算機語言怎樣實現呢?要實現我們還要考慮其初始狀況和結果輸出。所以除了前面的一部分,在該部分的前面和後面還應有相應的步驟。

‘準備工作,先將兩隻杯子中放入水,假設茶水是8,鹽水是5  

 b=8  

a=5  

‘真正開始交換  
 c=b  
 b=a  
 a=c  
‘將兩杯水擺到檯面上再看一下,是否交換正確  
 print a,b    

(以上用QBASIC語言寫成)

這就是程式,我們對電腦說的話,一定要符合事情發生的規律,也就是時間上的先後關係,要不然,電腦就不會做,或者給出我們一個和我們的期望完全不同的結果。

當然,聰明的您可能也發現了,用一個杯子來中轉交換的方法,還有第二種,只要將上面123改成321,將箭頭方向一轉就行了,再看一下圖,組成了一個迴圈往復的圓,逆時針和順時針轉都可以實現我們最終的目標。再找第三種方法,就很難想象了。 當然,照此發揮,如果我們再找來兩隻杯子,也可以,但做法會稍稍有所不同。 這就是程式,用在電腦中,就是用在電腦中用電腦語言來描述的讓電腦解決的一個問題的步驟,用一個術語來說明這個步驟,又叫做演算法。

2.1.3 用scratch實現

下面再以Scratch為例加以說明。

示例:水杯問題(Scratch版)

兩個同樣大小的茶杯a,b中盛有滿滿的兩杯水,一個杯a中是茶水(2),另一個杯b中也是水,只不過是汽水(6),請將兩杯水交換。 1、問題的三部分

輸入資訊:兩個杯和兩杯水,用具體的量來表達即,2,6 輸出資訊:還是兩個杯和杯中的水,只不過2,6的位置換了。 處理過程:前面進行過討論。此部分也可暫時不看,等到處理程式碼時再考慮。 2、定義變數

用到三個變數,分別代表三個水杯

enter image description here

圖2.1.3 Scratch積木程式碼

3、程式碼部分

這樣,水杯問題就得到了解決,在杯子a中輸入2,杯子b中輸入b,點一下執行按鈕,兩杯中的東西就交換了。

2.1.4 阿蘭開講

哥倫布可以發現新大陸,我們也可以發現電腦的新大陸;同樣,電腦的路可以不只有一條。哥倫布的故事給我們的啟示也許正是:幹什麼都要創造,程式設計也需要。程式設計需要步驟,創造步驟難,瞭解別人的創造容易,並且瞭解別人的東西也是我們後面創造的基礎。所以,本回的例子,是後面第七回和第八回的基礎,問題雖然簡單,但正是由這類簡單的問題最終形成了一個複雜的解決問題的組合體。 哥倫布發現美洲大陸的意義遠不止上面一個故事所能承載,但上面故事傳達的另一項重要的含義在於:交換或交流是非常重要的。交換是我們社會生活中不可缺少的普通的一部分,由於交換,使得我們各行各業中的人們得以彼此享受他人的服務,使得這個社會更加富足而美好。同樣的,交換在電腦的世界也非常重要,哥倫布的水杯問題雖然簡單,但誰能說複雜的問題就不是由象它一樣簡單的東西構成的呢?哥倫布水杯的另一重要性在於它是後面我們許多問題的解題基礎。 友情提示大家:過去的許多優秀人物和我們今天有類似的發現,只不過我們今天處在一個偉大的時代——電腦時代。

阿蘭告訴大家:壘積木就是在程式設計。

高樓大廈都是一磚一瓦建立起來的。我們程式設計比做一座樓,那麼,其中最基本的磚石是什麼呢?是依照時間次序做的一件件基礎性的工作。開始設計程式首先要選擇一種語言,還要有一個程式設計素材。但不管什麼樣的語言和素材,如果按時間和功能可以將程式分成三部分,輸入,處理和輸出。如果將三者看做一個整體,那麼程式就可以寫出一種最簡潔的形式:

第一步:輸入資料; 第二步:處理; 第三步:輸出結果。

通過三步,問題解決了,並在電腦上列出我們要的答案了。程式就是由形如上面三步的語句構成的,按照時間次序,不用拐彎,就可以將我們規定的任務由電腦做好。這就是順序結構,一種最簡潔的,我們用的最多的也不需要太多思考的程式設計方式。 如果從時間的角度來看,一個人不管經歷有多坎坷,任何人在時間這一點是都是沒有區別的,都是度過一個有前後次序的分分秒秒,如果用活一百歲來算,也就是三萬六千天,可以將天數從1、2、3一直編號到36500。 電腦處理事務也中此,不管任務有多大,從時間上來看,總有一種前後的脈絡關係,也可以編上1、2、3…類似的序號。

程式發展的基石就是這樣一種做事的次序。程式設計就是按照這個次序教電腦做事。

程式設計的問題其實就這麼簡單,哥倫布給了我們一個簡單的答案,還有更簡單地如同我們常聽到的小故事,究竟簡單到一個什麼程度呢?

2.1.5 小測驗:酋長

有一個酋長被懷疑得了傳染病(注意只是懷疑) ,要由三個醫生輪流檢查才能確定有沒有感染,而那三個醫生也有可能感染到,可是現在只剩兩副雙面都消過毒的手套,請問醫生們該如何檢查?

小測驗參考答案:

酋長問題中的關鍵是:一副手套的一面只能一個人使用,這樣就能保證四個人不會交叉感染,怎樣就能實現呢?具體到題中即一人一面。 四個人的關係通過三次檢查確定下來,所以其檢查可分成三步: 1、甲醫生給酋長檢查 2、乙醫生給酋長檢查 3、丙醫生給酋長檢查 但檢查的過程中還要保證一人一面,因為兩副手套只有四個面,所以酋長的面用了三次,其他各人的只能用一次,在上面三個步驟中必須保證這一點。用A和B分別表示兩副手套,用1,2表示內外兩面。操作的步驟如下: 1、甲醫生用B1給酋長面A2檢查,檢查時需將兩副手套套起來。 2、乙醫生用A1給酋長面A2檢查,檢查之前需將B手套脫下。 3、丙醫生給B2給酋長面A2檢查,檢查之前需將B手套內外翻轉,然後套在A手套中。

相關文章