程式演義第一一回 撒旦變臉並不可怕,本質亦須真知來抓

大大老狼發表於2016-07-16

2.11 上一節見識了一下神醫扁鵲兄弟三人的胖瘦,現在,我們再來看看西方一位以作惡而昭著的人物——它就是撒旦。
本回的目的是說明,看問題要把握其實質,抓住這一點,問題就好解了。抓實質是可以學到的。

2.11.1 P11撒旦變臉

enter image description here

圖:撒旦虛心聽取玩變臉敗因
撒旦(Satan),西方神話宗教人物,上帝和人類邪惡的敵人,通常被認為是墮落天使的領袖,不折不扣的惡魔,他有一個最好的把戲,是在不同人的面前可以顯現不同的面目——變臉。令撒旦想不明白的是,耶穌怎麼會有那麼多跟隨者呢?
有一天,耶穌帶領眾信徒上山傳教,撒旦也決定去看個究竟。第一天,他對徒弟們說,是我的徒弟的,你們一人撿兩塊石頭,跟我一起走。於是,徒弟們一人拿起兩塊石頭,向山上走去。撒旦心想,大的太重,於是撿了兩塊最小的石頭。到了山上,耶穌依次看,輪到撒旦了,拿到手中一塊大的,然後說:你是撒旦吧。撒旦很納悶,心想,一定是石頭拿的太小了,露餡了,灰溜溜地走了。 第二天,耶穌依然帶領他們上山,並且照舊讓他們每人撿兩塊石頭。撒旦變了另外一張臉,心想,昨天我撿了兩塊最小的,今天我要撿兩塊最大的。到了山上。耶穌還是輪著看,走到撒旦面前時,拿了塊大的,又笑著說:你是撒旦。撒旦又灰溜溜地走了。第三天,上山時,耶穌又讓他的徒弟們撿兩塊石頭。撒旦變了臉,心想:第一天我撿了兩塊最小的,第二天撿了兩塊最大的,都露了餡。今天我撿一大一小,不就萬無一失了嗎?於是他撿了一大一小兩塊石頭上了山。到了山上,耶穌還是輪著看,走到撒旦面前時,又挑了塊大的接下來,耶穌還是笑著說:你是撒旦!撒旦弄不明白的第二個問題是,耶穌怎麼老將我認出的呢?耶穌又笑著說,你的變臉遊戲挺不錯的,不過我給提點建議,在做之前,穿上鞋子,你是六指呀!撒旦當時昏倒在地!
我們的問題是:耶穌接過的三塊石頭,請按從大到小排一下?

2.11.2 五步積木法解題:

第一步:三積木 這是最簡陋一個圖形,也是最基本的一步,“目”形圖,我們略去,從第二步開始。

enter image description here

第二步:做頭尾
上面的三部分,先分析開頭和結尾部分,開頭是什麼呢?題中的已知條件,是三塊石頭重量,我們用a,b,c來表示。目標是什麼呢?是從大到小的三個數,怎樣表達呢?第一種方式是象上節的扁鵲石頭一樣,輸出還是用a,b,c,但這三個a,b,c和輸入的不盡一樣,輸入的值有六種可能,而輸出只有一種(如圖1B);第二種方式是直接輸出這六種方案中的一種(如圖1A)。
enter image description here

圖2B 圖2A

第三步:連頭尾

如何將開頭和結尾連線起來呢?我們也出現上面的兩種思路,第一種,我們可以繼續按照上節的做法,一步步下去,除了找到最大的,還要找出中間的,因為是三個數,所以最小的也就有了。怎樣才是真正的最大值,將這個過程分析一下,可以分成兩步,第一步,將a,b比較,使a>b;第二步,將a和c比較,使a>c,通過此兩步比較完成,a的值一定就最大了,如圖2B中間所示。還有是如何確定第二大的,這個問題只要一步就可解決,比較b,c,使b>c。所以該問題經過三步可解決。

第二種思路該如何解決呢?

輸出“六種方案中的一種”,當然要用分支結構,但一個分支又只能解決二選一的問題,怎麼辦呢?可以將這六種方案合成兩大類,後面可以再將合併的分開,問題就得到了解決(如圖2A示)。每一個分支中又包含了三種情況,所以還要將各自的三種情況再合併成兩種,通過分支解決,即分成二選一的情況和一種的情況,在二選一的情況中還要再用一個分支,由此我們可以看出,分支和分支巢狀了三層之多!(如圖3所示),三層中的邏輯關係,請大家可要仔細看好了。

enter image description here 圖3B 圖3A

第四步:貼語法

下面我們還用QBASIC語言來解這個題目。第三步圖中的各個語句和具體語言的語法還有一定的差距,根據相應語言,主要體現在輸入和輸出語句中,還要再行將相應語句轉化。

第五步:寫程式碼
下面可以寫程式碼了,兩個程式中,第一種方法的程式碼較簡單,第二種的程式碼比較難寫,但如果我們遵循下面的原則,也就比較簡單了,先整體分塊,然後從整體到部分。
第一種方法(如圖3B示),整個圖分成了五大部分,複雜一點是的中間的三部分,第一部分和最後一部分最簡單,寫的過程中要注意程式碼的開始和結束標誌。第一種程式碼如下:
input a,b,c
if a>b then
else
d=a
a=b
b=c
endif
if a>c then
else
d=a
a=c
c=d
endif
if b>c then
else
d=b
b=c
c=d
endif
print a,b,c

第二種方法(如圖3A示)整個圖可分成兩大部分,下面的分支們做為一部分,這部分比較複雜,上面的一部分原封不動照搬,非常簡單。寫完這一部分後,要注意先將下面的分支的框架形式寫好,然後通過填空的形式向上填,這樣就不容易出錯了,後面還要注意使用程式碼裡嵌風格,這樣更容易分清程式碼和程式碼的關係。程式碼如下:
所以程式碼如下:

input a,b,c
‘第一層分支
if a>b then
if c>a then
print c,b,a
else
if c>b then
print a,c,b
else
print a,b,c
end if
end if
else
if c>b then
print c,b,a
else
if c>a then
print b, c, a
else
print b, a,c
end if
end if
endif
(上程式在Qbasic下除錯通過)

2.11.3 阿蘭開講

程式演義到現在,由於分支結構的出現,解決的問題呈現出多姿多彩的形式,不管怎麼變,分支只有兩種形式,上下羅在一起形成一種順序關係,或巢狀在形成連環分支套加式,但不管怎樣,都是為解決更多種情況而存在的。
在我們將本題同兩個數排序的孔融的梨子比較一下,會有許多精彩的東西出現。一個最簡單,兩個稍複雜,三個更復雜,那面對一萬個呢?有意思的問題可能正在這裡,“3”是個有意思的數字,可能會因之而搔頭,也可能會因之而慨嘆!
阿蘭告訴大家的是:在程式設計方面,撒旦臉蛋的變化告訴我們的更重要的是,要抓住本質,也要學會找出規律,辦法總比困難多,笑著去面對,“上帝”也是這麼想的。
後面我們還將奉獻上這樣一些有意思的題目,進一步來看一下分支結構的特點,以迎接更復雜的分支問題的挑戰。欲知後事如何,且聽下節分解。

2.11.4 小測驗:求最大值

用本節介紹的方法,能求出三個數中的最大值嗎?如何求?

小測驗參考答案: 一種最簡單的辦法是,將六條輸出語句的後兩個變數的名稱去掉,只保留一個;如果您不怕麻煩,還可以通過三個分支語句巢狀的形式來完成。

相關文章