程式演義第一五回 唐僧設計水仙花搞怪,悟空裝痴一用計數器

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

上節講到大數學家高斯的解題妙法,下面,我們再見識幾位中國古代堅忍不拔的神話人物——孫悟空和唐僧。

enter image description here
圖:悟空回想三打白晶晶感言

2.15.1 P15唐僧的水仙花數

唐僧:俗家姓陳,乳名江流,法名 玄奘,唐朝第一高僧,所以被人們稱為唐僧。孫悟空:法號行者,是唐僧的大徒弟 ,會七十二變、騰雲駕霧。一雙 火眼金睛,能看穿妖魔鬼怪偽裝 的伎倆;一個筋斗能翻十萬八千 裡;使用的兵器如意金箍棒,能大能小,隨心變化。
唐僧十八歲出家皈依佛門,經常青燈夜讀,對佛家經典研修不斷, 而且悟性極高,二十來歲便名冠中國佛教,後來被如來佛祖暗中選中去西天取經,由孫悟空陪同保護,唐僧西天取經第一關,就是三打白骨精的白晶晶,以此為契機,伏妖降魔,終成正果。當他們重回大唐時,卻見到一派和平盛世圖景。打打殺殺的鏡頭已遠去也。
老唐和悟空閒來無事,經常到大大街那邊的白晶晶家去喝酒,時間長了,兩人對白晶晶好感日重,有一天悟空單獨來到白家,說出了埋藏在心頭多年的祕密:晶晶,其實我打你三次確實是無奈,唐老闆老是在身後以緊箍咒相逼,並且你老是帶一個號碼是371的牌子,不打你,連老唐那邊都不好騙呀?
白晶晶笑著說:悟空哥哥,那是發生在戰爭年代的故事,我不會怪你的,不過,我說件事,你也不要生氣。這個號碼叫做水仙花數,其實我帶這個牌子是和老唐的一種約定,不然,他怎麼知曉你是不是真心跟定他打工呢?
悟空聽完心裡打了個冷顫,一個問題也隨之出現:水仙花數是哪幾個數呢?(水仙花數是一個三位數,其各位上數的立方和等於這個數,例如上面提到的371。)
2.15.2 唐僧水仙花數解析
水仙花數既然是一個三位數,那麼它的範圍也就再清楚不過了,100-999,所以總計有900種可能的情況,挺嚇人的。這麼多的可能先暫且一放,讓我們再讀幾遍老唐挑出的這個特殊號碼——水仙花數,其有意思的地方是在數位和這個數建立了一種聯絡。怎樣破解這種聯絡呢?
1三位數和組成它的三個位
達芬奇(第六節)給了我們很好的啟示。既然是三位數,可進行如下的假設,各數位從高到低分別是a,b,c,那麼a,b,c和n之間有種一一對應關係。其實我們這裡的問題也就成了知道某個數來拆分其數位了。三個數位拆分如下:
a=Int(n/100)
b=Int((n-100*a)/10)
c=n-100*a-b*10
要看900個數,可以先看一個數,先任意挑選一個數過來,如何看看它是不是水仙花數呢?
2看看某個三位數是不是水仙花數
對於某一個三位數,假設用n代表,只有兩種可能,要麼是水仙花數,要麼不是。所以這個問題是個很簡單的分支問題,問題分成了三部分:條件,條件成立時的工作,條件不成立時的工作。後面兩部分最簡單,只要輸出相應資訊就行,關鍵是如何塑造條件。
怎樣判斷這個數是不是水仙花數呢?條件就是“各位上數的立方和等於這個數”。假設這個數是n,條件是個等式,條件中的後一部分很簡單,前一部分是各個數位:
條件也就有了 n=a * a * a + b * b * b + c * c * c
但在使用前,還必須將a,b,c求出來。求出來的工作在1中我們已經做了。所以最終的N-S圖也就成了圖1。

enter image description here

圖1

3看看900個數中哪幾個數是水仙花數
一個數我們已經分析完成,兩個數呢,只要將圖1再羅加上一遍就OK;三個也是如此,似乎可以一直推廣下去:
enter image description here

圖2
下面我們就寫程式碼吧,思考到這裡,心裡開始吸涼氣了,程式設計成了一種打字的體力活了!而電腦看著你費力地一個字母一個字母地向電腦裡錄入程式也不禁在嘲笑:真是個傻冒:)
怎麼辦呢?既然是這麼在規則地一致,那不將計數器加入其中,用迴圈來解題呢!
這裡用到的計數器,因為輸入的數是整數,從100到999,所以增量也是1(如圖3示)。
enter image description here
圖3
將重複的部分放到一個迴圈裡,問題解到此處,我們不禁為自己的聰明而叫絕。程式碼也就有了:
For i = 1 To 900
Input n
a = Int(n / 100) '拆分最高位
b = Int((n - 100 * a) / 10)'拆分10位
c = n - 100 * a - b * 10'拆分個位
If n = a * a * a + b * b * b + c * c * c Then
Print n ;” Shi ShuXianHuaShu”
else
Print n ;”BuShi ShuXianHuaShu”
End If
Next i

可當我們真刀真槍地在電腦上再試驗的時候,又會吐血:怎麼電腦老是要要求往裡輸數,老也輸不完(900遍啊)。電腦其實這時輕鬆地工作著,看著你笑:小樣的,比比誰幹的快!
我們和電腦比輸入數字,太不值了,怎麼辦呢?唯一的答案是:我們的迴圈程式還要變。細瞅一下程式,輸入的n值和迴圈變數i老是相差99,可不可以直接利用這個i呢,只要將input n 一句變換成n=i+99,問題不就成功解決了嗎?
現在,我們可以喝著茶水,看電腦的把戲了。但螢幕上的東西會令我們的眼珠子不好用了,螢幕上顯現的什麼東西,900行啊,怎麼我不需要的數字也給出現呢?所以,在“輸出”中還需要調整,對我們有意義的是水仙花數,那些不是水仙花數的東西,就不要讓他們出現在我們的面前吧!
幾經周折,我們的源程式有了:

For n = 100 To 999
a = Int(n / 100) '拆分最高位
b = Int((n - 100 * a) / 10)'拆分10位
c = n - 100 * a - b * 10'拆分個位
If n = a * a * a + b * b * b + c * c * c Then
Print n '輸出
End If
Next n

2.15.3 阿蘭開講
世上本沒有迴圈,但重複的問題多了,就出現了迴圈。迴圈是我們破解現實問題的有力工具,迴圈結構程式的本質是順序和分支,從這個意義上說,迴圈本質就是重複,但它又不是簡單的一成不變的重複。
使用迴圈,有三層境界:
第一層:重複的機械;
處在此階段的程式設計人員壓根就不知道迴圈為何物,他們程式設計,就象弱智的“打字員”在打字。電腦嘲笑弱智的“打字員”,程式還沒執行,但已經被書寫錄入程式碼累得半死了。
第二層:機械的重複
此階段的程式設計人員只知簡單迴圈,不知變通。電腦嘲笑弱智的除錯員,程式在執行著,我們以自己的弱勢專案同電腦的優勢專案火拼,那吃苦受累又不討好的只能是人。 第三層:重複的變通
電腦是一臺你的機器。以人的方式和它對話,但它以機器的方式工作著,人和電腦都找到自己的最愛。給人以人性化的關愛,給電腦以電腦化的關愛!
後面,我們還將繼續尋找這些規律,欲知後事如何,且聽下節分解。

相關文章