1. 程式人生 > >“自頂而下,逐步求精” 應用體會

“自頂而下,逐步求精” 應用體會

作為我們程式設計的初學者,不知道如何把現實中的問題,直接轉換到計算機的高階語言中,這裡就需要我們轉換思路,應用一種新的形勢,將看似複雜的問題變得簡單,看似凌亂的步驟變得有序,看似十分精確的語句,一點一點突破。

在處理程式碼問題的時候,普通常用函式和程式碼的記憶是編寫程式的基礎,而在這基礎之上,就是我們對於問題的分析能力,和轉換到程式碼的能力了。這個能力並不是與生俱來的,而是在觀察大量程式之後,通過自己的思想與總結,漸漸地形成一種慣性思維,進而演化為一種條件反射,能對一些基本簡單的套路在腦海中保留自己解決問題的模板。

當然,形成模板是大佬的常態。初學者需要對於一個單一的問題,提出自己的思考。面對看似複雜的問題,把看似形象的現實問題抽象出來,明確自己的目的,把大概的過程變成腦海中的虛擬碼,再經過註釋和進一步修復,變成計算機高階語言。這個過程就是我理解的“自頂向下,逐步求精”。

首先,看到窗臺上嗡嗡作響的洗衣機,用洗衣機舉一個小例子吧。
洗衣機是我們日常經常使用的家電,大家對洗衣機的正常工作程式肯定不陌生。簡單來說,洗衣機能進行三種最主要的功能。
1.正常洗滌
2.快速洗滌
3.脫水

首先是正常洗滌:這個程式的作用是利用充足的時間,將放在滾筒裡面的衣服洗滌乾淨,對於時間的要求並不高,但是對於潔淨程度要求高。所以逐步求精,我們可以大致地描述出程式的使用過程。

1.從使用者獲得程式
2.設定水位
3.開始注水
4.漂洗
5.浸泡
6.排水
7.進行三次注水 + 漂洗 + 排水
8.甩幹
9.報警

1.從使用者獲得程式,這個方式系統預設為正常漂洗:
Get the instruction
If operator doesn’t input anything, do rinse.
2.設定水位有兩種方式,如果沒有輸入水位,則呼叫感應系統進行體積質量感應,計算出將要注入的大概水位。
Get the instruction of water line.
If (operator doesn’t input anything )
order the sensing-system to get the approximate amount of water.
3.注水
Pour water in to the bucket.If there isn’t water source, warning.
4.漂洗
Do rinse for ten minute ,
If (the cover of the washing machine is open)
warning and cut the electricity;
5.浸泡
After the rinse , the machine should wait for twenty minutes to let the clothes get clean.
6.排水
Drain until there is no water in bucket.
7.三次沖洗
Int t = 3;
while (–t){
Input the correct amount of water,wash for ten minutes and drain.
}
8.甩幹
If (t == 0)
{
spin-dry the clothes in the bucket .
if(the cover is open) cut off tht electricity.
}
9.發出報警
Warning until them aster come。

下面,用舉一個自我的真實的例子。

UVA1588試題
這裡寫圖片描述
非常形象的圖形說明,好像張開的嘴中兩排牙齒,互相重疊之後讓兩排牙齒成功合上。
換算成資料就是這樣子了。
這裡寫圖片描述
給出兩行資料,之後1代表只有一個方塊,2代表只有兩個方塊,如何讓總體長度最短,使得兩組資料能成功合在一起?
這種題目,一定要用字串來做,但是設計到字串和整數型別的轉化,就需要動一番腦筋了。
這個非常典型的,把形象的物體圖形抽象成為計算機高階語言。我們可以採用自頂而下,逐步求精的辦法。

首先明確我們的目標,要輸出一個整數,這個證書是他們重疊之後的總長度,要求這個總長度為最小。
所以,我們首先把這個總程式寫成幾個虛擬碼
int main function
while input two lines of characters
make a character set that have 300 place and make another has 100 place.
let the top to the 100 th position of tht first character set
make another characerset;
let the position of the below changing like this.
這裡寫圖片描述


then make another function to judge if the addition of the same position is larger than three
if it is larger than three ,this pair is failed.
if all of them are less than three ,this pair is accepted.
then make less the least position that two pair take.
print the less.

大體上,包含:
主函式:輸入輸出,呼叫函式
判斷函式:判斷是否加起來之和小於三。
迴圈函式:從最左邊一位一個一個嘗試,呼叫判斷函式。

有了這三個函式,我打出了以下程式碼:
起到控制作用的主函式:
這裡寫圖片描述
判斷是否大於三的函式:
這裡寫圖片描述
承上啟下作用的迴圈函式:
這裡寫圖片描述

構思很好,但是發現了一個問題,發現我把top放在300 個位置的字串組中,不能輕易地呼叫strlen函式來判斷輸入的位數,也就沒辦法一個一個比對了。所以我只能自己再寫一個函式,來求top的位數:
這裡寫圖片描述
有了這個函式,即使前面有很多‘0’也不用擔心了。
在最終測試的時候,突然發現了一個問題。
因為我自頂向下,有了四個主要的板塊,看似是沒有問題了。
但接下來就是求精的過程。
發現在我main函式呼叫的時候,存在scanf()輸入top函式。而我之前top函式全部初始化為0。而在輸入字串之後,自動在末尾增添‘\0’導致我之後比對的時候出現bug。
我又不得不寫出另外一個函式,來修復這個bug,那就是把不可避免的’\0’強行放到最後吧。
這裡寫圖片描述

終於,看到了正確的結果。。。

這裡寫圖片描述

反思一下,從頭到尾,經歷了:分析題目、明確目的、寫虛擬碼,進行構思、寫主要板塊,修復。是“自頂而下,逐步求精”的一次實際的體現。當然有了“逐步求精”這四個字,意味著程式設計序的過程並不是一帆風順的,而更需要一步步地提升與修改。