🧠 主題 7:演算法設計與問題解決 💡
各位未來的電腦科學家好!這一章是整個課程中最重要的一章。為什麼呢?因為程式設計不僅僅是輸入代碼,它更是關於運用「邏輯思考」來解決問題。
我們將學習專業人士如何將一個模糊的構想,一步步轉化為能運作的電腦程式。就把這當作在開始烹飪前學習一份食譜吧!
1. 程式開發生命週期 (PDLC) (7.1)
當你要建立一個電腦系統時,不能直接跳進去寫代碼。你需要一個結構化的計劃,這個計劃稱為程式開發生命週期 (Program Development Life Cycle, PDLC)。它有四個主要階段:
階段 1:分析 (問題是什麼?)
在這個階段,你需要明確找出系統具體要做什麼。如果你在這裡弄錯了問題,整個程式都會是錯的!
- 識別問題與需求: 會使用什麼數據?使用者是誰?系統必須達成什麼目標?
- 抽象化 (Abstraction): 這意味著隱藏不必要的細節,只呈現最重要的資訊。
例子:當你看城市地圖時,你看到的是主要道路和地標,而不是每一棵樹或坑洞。這就是抽象化——專注於重要事物(路徑)。 - 分解 (Decomposition): 將一個大型且複雜的問題,拆解成較小、易於管理的部分(子系統)。
例子:製造機械手臂太龐大了,將其分解為:1. 手部動作控制、2. 手腕旋轉、3. 底座穩定。
階段 2:設計 (我們將如何解決問題?)
在這個階段,你在寫任何代碼之前先規劃好逐步解決方案。你會使用流程圖 (Flowchart) 和虛擬碼 (Pseudocode) 等工具。
- 分解: (這裡再次使用!) 我們將系統拆解為模組(子系統),這有助於我們分別設計每個部分。
- 結構圖 (Structure Diagrams): 展示主系統如何劃分為模組和子模組。
- 流程圖 (Flowcharts): 一種使用標準符號(如處理、輸入/輸出、判斷等)來展示邏輯流程的圖形化方式。
- 虛擬碼 (Pseudocode): 用於描述演算法的結構化英語。它使用程式設計關鍵字,但不綁定特定的程式語言。
💡 核心概念:IPOS 結構 (7.2)
在設計任何模組時,請務必考慮 IPOS 結構:
階段 3:編碼 (編寫解決方案)
這是將計劃(虛擬碼/流程圖)使用高階語言(如 Python 或 Java)轉換為實際程式碼的階段。此階段還包括反覆測試 (Iterative Testing)——即在編寫代碼時同步測試較小的程式部分。
階段 4:測試 (我們是否正確解決了問題?)
你使用各種類型的測試數據 (Test Data) 來執行程式,以確保它能按照需求運作,並能妥善處理未預期的情況。
重點總結: PDLC 確保你在開始編程前完全理解問題,這能節省日後大量的時間。分析與設計對於編寫優質程式至關重要!
2. 標準解決方法 (演算法) (7.4)
某些任務在程式設計中非常普遍,因此有標準且廣為人知的解決方案。你必須理解並能描述這些算法:
1. 加總與計數
這是最簡單的演算法。
- 計數 (Counting): 用於追蹤事件發生的次數。你需要一個計數器變數,初始值為 0,每發生一次事件就加 1。(例如:統計得分超過 80% 的學生人數。)
- 加總 (Totalling): 用於累加數值總和。你需要一個總和變數(累加器),初始值為 0,在每次迴圈中加入新的數值。(例如:計算購物車中商品的總價。)
2. 找尋最大值、最小值與平均值
要找最大值/最小值,你通常會假設輸入的第一個值即為最大(或最小)值,然後將隨後的每個值與之比較,如果發現更大或更小的值,就更新你的變數。
- 平均值: \( \text{Average} = \frac{\text{Total}}{\text{Count}} \)
3. 線性搜尋 (順序搜尋)
透過從頭到尾逐一檢查列表(陣列)中的每個項目,來尋找特定目標。
- 運作方式: 從位置 1 開始。將搜尋值與列表中的項目進行比較。如果相符則停止;如果不相符,則移動到下一個位置。重複此過程直到找到目標或到達列表末尾。
- 你知道嗎? 這個方法很簡單,但對於很長的列表來說速度很慢。
4. 氣泡排序 (Bubble Sort)
用於將列表項目進行排序(升序或降序)。之所以叫氣泡排序,是因為最大(或最小)的值會像氣泡一樣「浮」到正確位置。
- 運作方式: 重複遍歷列表,比較相鄰元素,如果順序錯誤則交換它們。此過程會重複直到整個過程都不需要交換為止,代表列表已排序完成。
- 類比: 想像汽水杯中實際的氣泡。最大、最輕的氣泡會隨著反覆的擾動最終上升到頂部。
重點總結: 這些標準演算法是大多數程式的基石。請務必練習如何為氣泡排序或線性搜尋編寫虛擬碼!
3. 數據完整性:驗證 (Validation) 與核實 (Verification) (7.5 & 7.6)
數據完整性意味著確保數據準確且合理。我們主要使用兩種方法:驗證與核實。
3.1 數據驗證 (Data Validation) (7.5)
驗證 (Validation) 是檢查輸入的數據是否合理 (Reasonable) 與有意義 (Sensible),但它不能保證數據 100% 正確。
- 範圍檢查 (Range Check): 檢查輸入是否在預設的最大值和最小值範圍內。
例子:測試分數必須在 0 到 100 之間。 - 長度檢查 (Length Check): 檢查數據是否包含所需數量的字元。
例子:密碼必須正好 8 個字元長。 - 類型檢查 (Type Check): 檢查輸入的數據類型是否正確。
例子:數量欄位必須輸入 INTEGER(整數),不能輸入文字。 - 存在檢查 (Presence Check): 檢查欄位中是否已輸入數據(即欄位不能留空)。
例子:姓名欄位不能為空。 - 格式檢查 (Format Check): 檢查數據是否符合特定的格式或結構。
例子:英國郵遞區號格式必須為 'LLNN NLL' (如 SW1A 0AA)。 - 檢查位元 (Check Digit): 從數字的其他位元計算出的額外數字(如 ISBN 或條碼)。它能確保輸入錯誤(如打字錯誤)被檢測出來。
🧠 記憶小撇步:驗證就是檢查「合理性」!
記住 V.A.L.I.D.A.T.I.O.N.,這些檢查是為了確保數據是合理 (Reasonable) 的,但不一定保證數據正確。
3.2 數據核實 (Data Verification) (7.6)
核實 (Verification) 是檢查輸入系統的數據是否與原始來源數據一致。它確保在數據傳輸或輸入過程中的準確性。
- 視覺檢查 (Visual Check): 使用者直接對照螢幕上的輸入內容與原始來源文件(例如檢查表格)。
- 雙重輸入檢查 (Double Entry Check): 數據輸入兩次,可能由不同人輸入,或由同一人輸入兩次。電腦會比較兩次輸入結果,如果相符,則接受該數據。
重點總結: 驗證檢查輸入是否「可能」(例如:99 分是一個可能的分數嗎?);核實檢查輸入是否「準確」(例如:紙上寫的是 96 分,我是否有誤打成 99 分?)。
4. 測試與除錯 (7.7 & 7.8)
好的程式必須經過徹底測試。我們需要使用特定的測試數據類型,以確保程式能處理所有狀況。
4.1 測試數據類型 (7.7)
- 正常數據 (Normal Data): 預期中的、有效的,且在可接受範圍內的數據。
例子:如果有效範圍是 1 到 100,正常數據可以是 50。 - 邊界數據 (Boundary/Extreme Data): 位於可接受範圍邊緣的數據,以及最大/最小的不可接受值。
例子:若 1 到 100 有效,測試 1 和 100(邊界值),以及 0 和 101(無效的邊界值)。 - 異常數據 (Abnormal Data): 完全無效、且超出預期類型或範圍的數據。
例子:在預期 1 到 100 的數字欄位中輸入 "potato"。
4.2 追蹤表 (Trace Tables / Dry Runs) (7.8)
追蹤表 是手動檢查演算法邏輯的重要工具(此過程稱為 乾跑 (Dry Run))。
- 為演算法中使用的每個變數建立欄位,並為任何輸出和使用者提示建立欄位。
- 逐步執行演算法,隨著變數值的改變更新表格中的數值。
- 這有助於你在編寫實際代碼前,發現設計中的邏輯錯誤(臭蟲)。
如果剛開始覺得這有點難,別擔心;透過簡單的迴圈和選擇語句多加練習,追蹤表會變得非常容易!
4.3 解釋演算法用途 (7.3)
在考試中,你可能會被要求解釋某個演算法的功能。你的答案必須包含兩部分:
- 說明目標: 清晰定義該演算法的目標 (例如:「該演算法找出使用者輸入的最大值。」)
- 描述處理過程: 解釋它是「如何」達成目標的 (例如:「它使用迴圈讀取 10 個輸入,將每個輸入與名為 MaxValue 的變數比較,如果新輸入值較大,則更新 MaxValue。」)
重點總結: 測試需要使用不同類型的數據進行刻意練習。追蹤表是你用來查找邏輯錯誤的「手動」方法。