第四章 決策敘述 4-1 if 4-2 if..else 4-3 case 4-4 綜合範例
人類的生活必須不斷的面臨選擇、決策問題,連我家一個不到三歲的小孩,也常要思考他手裡的十元是要坐電動車還是買棒棒糖。程式語言是協助人類解決問題的工具,當然也包含決 策敘述,Delphi依決策點的多寡,分為以下三種決策敘述: 第一是單一分岐決策的if,例如肚子餓了就吃飯 第二是雙向分岐決策if else,例如肚子餓了就吃飯,否則繼續前進; 第三是多向分岐決策的case,例如你身上有5000元,走進一家五星級的大飯店用餐,你的分岐點就很多,可選擇自助餐、中式套餐、日本料理、泰國餐點等等分岐點。 本章的重點即是探討Delphi的決策敘述。
4-1 if if通常用於單一分岐的決策,它的使用時機為“假如~則~”,也就是條件成立時,則執行某項工作,若條件不成立時,將不予理會。 其語法如下: if 運算式 then begin 敘述區塊 ; end; 以上語法說明如下: 1.若所要執行的敘述區塊只有一個,則可以省略上下的begin與end,只寫為: 單一敘述 ;
其次,因為條件成立時,只有執行一個敘述,所以begin...end可省略,如以下述。 2. 若運算式的值為True(條件成立),則執行敘述區塊;運算式的值若為False(條件不成立),該敘述則不會被執行,其流程圖如下: 例如,以下敘述,當a的值大於60分時,可設定b為及格。 if a>=60 then begin b:="及格" ; end; 其次,因為條件成立時,只有執行一個敘述,所以begin...end可省略,如以下述。 b:='及格';
範例4-1a 請輸入一個成績,若此成績大於等於60分,則輸出“及格”。 本例即是單一分岐決策的典型範例,當條件成立時則執行某個敘述。 本例的if敘述區塊,僅有一個敘述,所以上下的begin與end讀者可自行省略。
範例4-1b 同上範例,但及格時背景以黃色呈現。
範例4-1c 請輸入兩數,並求其較大值 [演算法則] 1.輸入第一數,本例以實數a儲存。 2.輸入第二數,本例以實數b儲存。 3.設定極大值(max)為第一數。 max=a 4.當第二數(b)大於極大值時,極大值即以b取代。 if b > max then max:=b; 5.輸出極大值(max)即為所求。
自我練習 請輸入兩個數,並求其最小值。
範例4-1d 請輸入三個數,並求其最大值 1.輸入第一個數,本例以實數a儲存。 2.輸入第二個數,本例以實數b儲存。 [演算法則] 1.輸入第一個數,本例以實數a儲存。 2.輸入第二個數,本例以實數b儲存。 3.輸入第三個數,本例以實數c儲存。 4.設定極大值(max)為第一數。 max:=a; 5.當第二數(b)大於極大值時,極大值即以b取代。 if b> max then max:=b; 6.當第三數(c)大於極大值時,極大值即以c取代。 if c> max then max:=c; 7.輸出極大值max。
自我練習 1.請輸入四個數,並求其最小值。 2.請輸入五個數,並求偶數的個數。
範例4-1e 請輸入兩個數,並將此二數交換後輸出 [演算法則] 1.輸入第一個數,本例以實數a儲存。 2.輸入第二個數,本例以實數b儲存。 3.設定暫存的實數t。 4.將實數a指定由實數t儲存。 t:=a 5.將實數b指定由實數a儲存。 a:=b 6.將實數t指定由實數b儲存。 b:=t 7.輸出a,b兩數,即為交換後的結果。
範例4-1f 請寫一個程式, 可以輸入三個數,並由小而大輸出 〔補充說明〕 1.以下是將資料交換寫成程序,關於程序的用法請看8-1節 2.若有4筆資料要排序,則共需進行6次比較與交換 3.若有5筆資料要排序,則共需進行10次比較與交換 4.以上為3,4或5筆資料的比較與排序,其比較與交換的次數尚可克服,但若欲排序的資料超過5個,例如20筆資料欲排序,則應待迴圈與陣列敘述介紹之後,才有較快速的解法。 〔演算法則〕 1.分別以a、b及c表示欲排序的資料。 2.假如a大於b,則a與b交換 3.假如b大於c,則b與c交換 4.假如a大於b,則a與b交換,排序完成 並需進行3次的比較與交換
自我練習 1.請寫一個程式,可以輸入4個數,並由小而大排序。 2.請寫一個程式,可以輸入5個數,並由大而小排序。
4-2 if..else if 運算式 then begin 敘述區塊1 ; end; else 敘述區塊2 ; 上一節的if僅適合單一分岐的決策,當條件成立時執行某一敘述,當條件未成立時,則未做任何處理。但在日常生活領域,常出現“假如~則~,否則~”,此種決策模式有兩種解決問題的方案,故稱為雙向分岐決策,此時可使用if..else敘述,其敘述語法如下: if 運算式 then begin 敘述區塊1 ; end; else 敘述區塊2 ;
1.若敘述區塊內只有單一敘述,則begin與end可以予以省略,如下所示。請留意敘述1之後不用加分號(;),因為整個if敘述尚未結束。 以上語法說明如下: 1.若敘述區塊內只有單一敘述,則begin與end可以予以省略,如下所示。請留意敘述1之後不用加分號(;),因為整個if敘述尚未結束。 if 運算式 then 敘述1 else 敘述2 ; 2.運算式的值若為True,則執行敘述區塊1;運算式的值若為False,則執行敘述區塊2 3.以下程式片段可依a的大小評量其及格與否。 if a>=60 b="及格" b=“不及格”; 4.敘述區塊內可以放置任何合法敘述,當然也可以再放置if。if中有if,稱為巢狀if。 例如,以下敘述除可判斷a是否及格,更可判斷其是否優等。 if a>=60 then begin b='及格"; if a>=90 then c:='優等'; end;
範例4-2a 同上範例,加上當成績小於60時,也要印出"不及格"。 本例是典型的雙向分岐決策,此時可用if…else實現程式的要求。 本例的if及else敘述區塊均只有一個敘述,所以begin與end可自行省略。
範例4-2b 請寫一個程式,完成以下要求: 輸入一個0~100的分數。 當分數大於90分時,輸出A。 當分數介於80~89分時,輸出B。 當分數介於70~79分時,輸出C。 當分數介於0~69分時,輸出D。 以上每一個決策點,都有兩個分岐點,所以適用if...else,每一個else後面均需再放置if作進一步決策。
範例4-2c 同上範例,但90分以上時,背景以黃色顯示;分數低於70分時,背景以紅色顯示 補充說明: Delphi的語法是承繼Pascal,其是否加分號的規則表面上看起來比較亂,此點在後續的程式語言如C/C++、Java均已有改進。
自我練習 請寫一個程式,可以輸入(x,y)座標而得其所在象限。例如,輸入(3,4)輸出"Ⅰ";輸入(-5,2)輸出"Ⅱ"。
4-3 case 一個決策點若同時擁有三個或三個以上的解決方案,此稱為多向分岐決策。多向分岐決策雖也可使用範例4-2b的巢狀if ...else解決,但卻增加程式的複雜度、及降低程式可讀性。 若決策點能找到適當的運算式,能使問題同時找到分岐點,則可使用case敘述,其語法如下:
case 運算式 of 結果1 : begin 敘述區塊1; end; [結果2 : 敘述區塊2; end;] . . [else: 敘述區塊n; end ; //此處的分號代表一個case敘述的結束。
語法說明: 1. case的運算式必須可以得到一個序數(Ordinal)的型態,例如 整數3或字元'B'。 2. 每一個結果也必須是序數型態(整數或字元),但可以是連續 的序數,例如3、3..6、'B'或'B'..'E'等。 3. 程式將依運算式的結果,尋找適當的敘述區塊。 4. 以下敘述,可將所輸入的a值,轉為對應的星期幾。 case a of 0: b:= '星期一'; 1: b:= '星期二'; 2: b:= '星期三'; 3: b:= '星期四'; end;
6. 敘述區塊內可放置任何合法的敘述,當然也可放置 switch或if 5.若沒有適當的“結果”可以執行,程式將會自動離開case敘述。 為了避免發生這種情況,可以在程式的最後面加上else,使得 即使沒有任何結果符合時,也可以執行else後面的敘述。例如,以下敘述,若使用者輸入的值不在0與6之間,則會顯示 “輸入錯誤”。 case a of 0: b:= '星期一'; 1: b:= '星期二'; 6: b:= '星期日'; else b:= '輸入錯誤'; end; 6. 敘述區塊內可放置任何合法的敘述,當然也可放置 switch或if
範例4-3a 試以case重作範例4-2b。 補充說明: case敘述內的每一個結果,若要執行兩個以上的敘述時,則要使用begin與end圍起來、且要以分號(;)結束。
範例4-3b (1)當輸入是0,1,2,3,4時,輸出"綠燈"。 (2)當輸入是5,6,7,8,9,10時,輸出"綠閃" 請寫一個紅綠燈的模擬程式,其要求如下: (1)當輸入是0,1,2,3,4時,輸出"綠燈"。 (2)當輸入是5,6,7,8,9,10時,輸出"綠閃" (3)當輸入是11,12時,輸出"黃燈"。 (4)當輸入是13,14,15,16,17時,輸出"紅燈"
範例4-3c 〔操作步驟〕 1.本例為使a值流通於各事件副程式,所以宣告於表單的變數宣告區,如以下敘述。 Var Form1:TForm1; 同上範例,但改為每按一次按鈕,輸入值自動遞增,並輸出相對的燈號。 〔操作步驟〕 1.本例為使a值流通於各事件副程式,所以宣告於表單的變數宣告區,如以下敘述。 Var Form1:TForm1; a:integer; 2.交通號誌的三個燈號,本例使用三個shape(位於Additional標籤)元件。 其name屬性分別設為sppgreen,shpyellow及shpred,其shape屬性均點選stCircle,其Brush.color則分別點選clGreen,clYellow及clRed。 3.本例將"綠閃"再分為"綠減"與"燈燈",待下一範例即有綠閃的效果
範例4-3d 同上範例,但改為自動遞增輸入值。 〔操作步驟〕 1.本例新增一個Timer元件(位於System標籤),其Name屬性預設值為Timer1,並設定其interval屬性為1000(表示每1000ms自動產生一個OnTimer事件。) 2.將上例TForm1.btn startClick副程式的內容剪下,並貼至TForm1.Timer1副程式,如以下的程式列印。 3.關於Timer元件的詳細用法,請看12-12節。
4-4 綜合範例 一元二次方程式 解一元二次方程式的演算法如下: 1. 設有一元二次方程式如下: ax2 + bx + c = 0 4-4 綜合範例 一元二次方程式 解一元二次方程式的演算法如下: 1. 設有一元二次方程式如下: ax2 + bx + c = 0 2. 若a = 0則應輸出“輸入錯誤” 3. 令d=b2-4ac 4. 若d = 0,則方程式有唯一解 ; 若d > 0,則方程式有二解: , , 否則無實數解。
範例4-4a 請設計一個程式, 可以解一元二次方程式 1. 使用edia、edib及edic分別輸入方程式的三個係數a、 b及c。 2. 使用lblOut輸出結果。 程式說明: 1. Delphi並無次方與根號運算子,若欲使用次方或根號運算,則應使用intpower、power或sgrt等數學函式,且應於uses連結檔宣告區中,引用數學函式如下: uses Math; 2. intpower、power或sgrt等數學函式,計算結果均傳回實數的Extended型態,請特別留意資料型態的一致。
二元一次方程式 解二元一次方程式的演算法如下: 1. 設二元一次方程式如下: 1 2 2. 令 (表示d = a1b2 - a2b1) 1. 設二元一次方程式如下: 1 2 2. 令 (表示d = a1b2 - a2b1) 3. 假如 則方程式無限多解,且程式結束
4.假如d = 0,則程式無解,且程式結束 5. 6.
範例4-4b 請設計一個程式,可以解二元一次方 程式。
三角形面積 若已知三角形三邊長,計算三角形三邊長的演算法下: 1. 輸入三角形三邊長a、b、c。 3. 最小的兩邊之和若小於等於第三邊,則此三邊未 能構成三角形,程式提早離開。 4. 假如則為銳角三角形,否則,假如則為直角三角 形,否則此三角形為鈍角三角形。 5. 令 6. 三角形面積
範例4-4c 請輸入三角形三邊長,首先判斷是否構成三角形。 其次,判別三角形的種類,最後計算其面積。 程式說明: 1.設有a,b,c三數,欲由小而大排列,則其演算法如下: a,b比較,若a>b,則兩者交換。 b,c比較,若b>c,則兩者交換,此時c一定最大。 a,b再比較,若a>b,則兩者交換,此時a一定最小。 共比較三次,即可由小而大排列。 2.假如有兩杯水a,b要交換,則其交換演算法如下: 先找一個空杯子t。 將a的水暫時倒入空杯子t(t := a)。 將b的水倒入a杯子(a := b)。 將t的水倒入b杯子(b := t),而完成兩杯水的交換。 如果未找來空杯子t,而直接將a倒入b,則原來b杯子的水就不見了。 3.本例使用power函式,要記得引用數學函式(uses Math)。
閏年 閏年的判斷 1.西元的閏年為每400年必須有97次閏年,其規劃方式如下: (1) 4的倍數。依此條件共有100次。 閏年 閏年的判斷 1.西元的閏年為每400年必須有97次閏年,其規劃方式如下: (1) 4的倍數。依此條件共有100次。 (2) 於(1)的條件,扣掉100的倍數。依此條件,共有96次。 (3) 於(2)的條件,再加回400的倍數。所以共有97次。 2. 測試資料如下: 西元年分 性質 流程路線 3 平年 (1) 4 閏年 (2) 100 (3) 200 300 400 (4) 600 1200 2000
範例4-4d 閏年的判斷。
習題 1.試寫一程式由使用者輸入一數值,並由電腦判斷其為奇數或偶數 2.假設所得稅稅率法則如下: 淨所得30萬以下6%。 淨所得30~80萬之間13%。(前面的30萬仍扣6%,超過30萬的部分稅率為13%,不是全部都扣13%) 淨所得80~200萬之間21%。 淨所得超過200萬30%。 試寫一程式可以輸入淨所得,並計算應繳稅額。 例如淨所得若為40萬,則其納稅金額計算如下: 30×6% + 10×13% = 21000 (超過30萬的部份稅率為13%,不是全部40萬都是13%)
x2 1<=x<=3 y=f(x)= x 0<x<1 0 x<=0 4.某一貨品定價100元,若購買500件(含)以上打7折,若購買499~300件則打8折,若購買299~100件則打9件,購買100件以下則不打折,試寫一程式可以輸入購買件數而得總價。