程式演義第一六回 才子選秀求破局,東坡腦動來編號

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

上一回神話人物的非人的計算能力,現在,再回到一千年前的中國,來看看一位二千年才可能有的天才,蘇東坡。

2.16.1 P16 東坡編號

enter image description here
圖:東坡編號感言
蘇軾,生於1037年1月8日,逝於1101年8月24日,字子瞻,號東坡居士,是中國古代有名的才子,詩書畫無不精通,醫理天文地理無不通曉,就是算術能力,也不弱於一般人,逐漸成為文人雅士中的領袖。 在大宋的盛世中,不乏類似的選秀活動,四大才子一項的出爐,是給文人至高的名譽。文壇領袖東坡針對這項活動,有了自己的創舉。
我們的問題是:四大才子的十個候選人中,如何從高到底給他們打分排名?

2.16.2東坡編號解析
第一步:從“3”個說開去
現在,我們不能只劃“目”式框框了,而要有所承接,先回顧一下撒旦變臉中的方法之一,定好目標,然後向目標努力的方式。

enter image description here

圖1
第二步:編號

上面的程式中,三塊石頭重量,用a,b,c來表示。目標是什麼呢?輸出還是用a,b,c,但這三個a,b,c,進一步,能否將這三個a,b,c,用另外的形式來替換一下,即編號的形式a1,a2,a3。通過這種下標式編號,便於後面找出其中的規律,便於更大程度上更方便地創造出“形似神不似”的形式。

enter image description here
圖2
第三步:推導一般形式
下面,需要通過圖2中的編號形式,進一步發現一般形式。對於三個數排序,如何看四個、五個直到N個數排序?
首先可以觀察到,上面程式中,三個分支是何其相似,只有數字的部分是變化的,其共同特點也就有了(如圖3),其相似部分成了一個迴圈式的分支了。下面的工作,就是進一步這其中的規律找出來,通過看編號的數字的形式,找出其中的這種變化。這就是問題的研究方向。先編上編號,最終還是要將這個標號除掉,有了規律,編號就去除了,這就是編號的作用所在。
enter image description here

圖3

要將上面猜測中的統一圖景變成現實,還需要找出切實的規律來。如果是a1,a2,a3,a4,中間的分支塊的個數會是多少呢?進一步類推,對於任意N多的數排序,分支的塊數又是多少?這個規律是研究如何用迴圈解題的基礎,一個儘量相似、儘量多的相似的挖掘問題。
從兩個開始,a1>a2,只有這個分支。
到了三個,成了a1>a2,a1>a3;a2>a3。
如果是四個,會是a1>a2,a1>a3,a1>a4;a2>a3,a2>a4;以及a3>a4。
如果是五個,會是a1>a2,a1>a3,a1>a4,a1>a5;a2>a3,a2>a4,a2>a5;以及a3>a4,a3>a5,和最後的a4>a5。

就用上述四個整理和總結,問題基本就出來原貌了。當然這個過程真地需要訓練和苦想,可以思考出很多種不同的形式。下面介紹一種。
規律:
第一個編號需要和比他編號小的進行比較,如果沒有比它小的,就不用比了。沿這種形式,因為是兩個變數,我們找出前一個和後一個變數下標數字的變化特點:

2個:12,
3個:1213,23
4個:121314,2324,34
5個:12131415,232425,3435,45

……
圖:數字規律圖
整體觀察一下,可以拿4個的情況來看。只要把這一個的規律找出來,其他的與它類似。
逗號分隔的部分,都有一個最大的特點是,前一個比較的數是1,2,3,4,直到下標比最大下標小1,而後,它要和比它大的下標代表的數去比較,直至下標達到最大。
所以先做內部的一個,即由“,”分隔開的小部分,這裡可以取第一逗號前的,也可以取第二個逗號前的,假設第幾個逗號用變數k1表示,

a(k1)與a(k1+1)比較
a(k1)與a(k1+2)比較
a(k1)與a(k1+3)比較
..
進行比較的下標最大值正好是變數的個數。
為了方便,不能將兩個比較者都用k1,我們起用另一個變數k2:

上面的都合成一句,但這一句中k2的值有一個範圍,最小的是k1+1,最大的則是k1+(比較變數個數-1),每次增加一1,現在只一句,重複一下就可以了。
a(k1)與a(k2)比較
所以就有了一個統一的式子,假設最大的下標數即比較的變數的數目是i,則可用下面的圖來描述內部的比較:
enter image description here
圖 “,”號分隔區內部比較

現在,可以再以這個塊為整體,進一步地以這個整體去看,k1的變化,即上面的圖中k1取值從1開始,直至比較變數個數的最大值減1,即i-1。而每次還是增加一個。所以可以另外再用一個計數器來完成。
enter image description here
圖 順序式的k1變數示意圖

假設總計有i個數參與排序,這樣,可以進一步整合上面的圖,將外面通過計數器做成一個迴圈的形式,總共安排兩個迴圈中來模擬,值得注意的是,這兩個迴圈是巢狀在一起的:

enter image description here
圖4
最重要的部分出爐了,還需要將其頭部和尾部放好:
enter image description here
圖5
第四步:貼語法
第三步圖中的各個語句和具體語言的語法還有一定的差距,根據相應語言,可能體現在輸入和輸出語句中,也可能體現在具體的應用工具中,還要再行將相應語句轉化。
上圖中a()的形式,是陣列的形式,但Scratch中沒有這一形式,所以,需要通過其連結串列來代替。

第五步:寫程式碼
下面可以寫程式碼了,兩個程式中,第一種方法的程式碼較簡單,第二種的程式碼比較難寫,但如果我們遵循下面的原則,也就比較簡單了,先整體分塊,然後從整體到部分。
enter image description here

2.16.3阿蘭開講
程式演義到現在,我們意識到規律的重要性,更意識到一個好的利於找規律的方法更重要,有道是:工欲善其事,必先利其器。東坡的編號方法,就是一個有利的武器。因為有了這個武器,這種方法,可以使我們從繁雜的問題轉換成簡單的數字遊戲。
在我們將本題引伸一下,研究一下兩個數排序,三個數排序,到十個,再到成千上萬的N,會有更多的發現。“3”是個有意思的數字,可能會因之而搔頭,也可能會因之而慨嘆!3之後呢,通過編號的形式,可以更好地發現規則,傾角3的危機。
阿蘭告訴大家的是:在程式設計方面,除了要抓住本質,還要學會創造條件來找出規律,辦法總比困難多,有利的武器曾來不缺少,只是不曾用。
後面我們還將奉獻上這樣一些有意思的題目,進一步來看迴圈規律的特點。欲知後事如何,且聽下回分解。

2.16.4小測驗:求最大值
用本回介紹的方法,能求出三個數中的最大值嗎?如何求?

相關文章