歡迎來到演算法的世界!

你好!今天我們將深入探討電腦科學中最重要的部分之一:演算法(Algorithms)。別被這個名詞嚇倒了——演算法其實就是為了解決問題或完成任務而設計的一系列步驟指令。無論是你跟著食譜烤蛋糕,還是告訴朋友怎麼去你家,你在日常生活中其實已經在使用演算法了!

在本章中,我們將學習如何設計這些指令,讓電腦能夠理解它們,學習如何找出錯誤,以及如何讓我們的解決方案運作得盡可能快。

1.1 建構基礎:分解與抽象

在編寫演算法之前,我們需要像電腦科學家一樣思考。我們透過運算思維(Computational Thinking)來做到這一點。其中兩個最重要的工具是分解(Decomposition)抽象(Abstraction)

分解

分解是指將複雜的問題拆解成較小、較易處理的部分。
例子: 如果你想製作一款電子遊戲,你不會只是「編寫遊戲」。你會把它拆解為:1. 角色移動、2. 計分系統、3. 圖像顯示,以及 4. 音效。解決四個小問題比解決一個大問題要容易得多!

抽象

抽象是指移除不必要的細節,將焦點放在重要的部分上。
例子: 看看倫敦地鐵圖。它不會顯示每一條街道或建築物,它只顯示車站和路線。透過抽象化那些額外的細節,地圖變得更容易使用。

副程式

副程式(Subprogram)是一小段用來執行特定任務的程式碼,可以在需要時隨時「呼叫」它。
副程式的好處:
• 你不需要重複編寫相同的程式碼。
• 它使程式更容易閱讀和測試。
• 不同的人可以同時編寫不同的副程式。

快速回顧:分解 = 拆解問題。抽象 = 簡化資訊。副程式 = 可重用的程式碼塊。

1.2 演算法的表示方式

在我們將演算法輸入電腦之前,主要有兩種「繪製」或「編寫」演算法的方法:流程圖(Flowcharts)虛擬碼(Pseudocode)

流程圖

流程圖使用不同的形狀來顯示程式執行的路徑。以下是你必須知道的形狀:
橢圓形(終止符): 用於「開始」和「結束」。
平行四邊形: 用於輸入(例如:詢問姓名)和輸出(例如:顯示結果)。
矩形: 用於處理(例如:像 \(x = y + 2\) 這樣的運算)。
菱形: 用於決策(例如:「分數是否大於 50?」)。這個形狀總是有兩個箭頭伸出:一個用於「是/真(Yes/True)」,另一個用於「否/假(No/False)」。

虛擬碼

虛擬碼是一種編寫指令的方式,它看起來像程式語言,但使用的是平實的英文。它沒有嚴格的「文法」規則,所以你不必擔心漏掉分號!
例子:
OUTPUT "請問你的年齡是多少?"
INPUT userAge
IF userAge >= 18 THEN OUTPUT "你可以投票!"

1.3 程式設計結構

世界上每一個演算法都是由三種基本結構構建而成的:

1. 順序(Sequence): 按特定的順序,一個接一個地完成指令。
2. 選擇(Selection): 使用 IFTHENELSE 進行選擇。
3. 迭代(重複,Iteration): 多次循環執行指令。有兩種類型:
    • 計數控制: 當你知道確切重複次數時使用(例如:FOR 迴圈)。
    • 條件控制: 當你希望重複執行直到某個條件改變時使用(例如:WHILE 迴圈)。

關鍵總結: 每個程式都只是步驟(順序)、選擇(選擇)和循環(迭代)的組合。

1.4 運算子與數據

為了進行運算和決策,我們使用運算子(Operators)。可以把這些想像成你演算法中的「動詞」。

算術運算子

這些用於數學運算:
加法: \(+\)
減法: \(-\)
乘法: \(*\)
除法: \(/\)
整數除法(DIV): 告訴你一個數字能被另一個數字除幾次,並忽略餘數(例如:\(7 \text{ DIV } 2 = 3\))。
模數(MOD): 只告訴你餘數(例如:\(7 \text{ MOD } 2 = 1\))。
指數: \(^\)(例如:\(2 ^ 3 = 8\))。

關係與邏輯運算子

這些幫助電腦進行決策:
關係: ==(等於)、!=(不等於)、<(小於)、>(大於)。
邏輯: AND(兩者必須同時為真)、OR(至少一個為真)、NOT(反轉結果)。

常見錯誤: 不要混淆 ===。在許多程式語言中,單個 = 用於設定數值(賦值),而 == 則是詢問「它們相等嗎?」(比較)。

1.5 尋找與修正錯誤

即使是最優秀的程式設計師也會犯錯!你需要知道以下三種錯誤類型:

1. 語法錯誤(Syntax Error): 程式碼中的「文法」錯誤(例如:將 PRINT 拼寫為 PRUNT)。程式將無法啟動。
2. 邏輯錯誤(Logic Error): 程式可以執行,但給出的答案是錯誤的。例如,你想將兩個數字相加,卻不小心輸入了減號。
3. 執行階段錯誤(Runtime Error): 程式在執行過程中發生的錯誤,導致崩潰(例如:要求電腦除以零)。

追蹤表

追蹤表(Trace Table)是一種用來追蹤變數數值的工具,當你逐行執行演算法時,它可以幫助你找出邏輯錯誤
如何使用: 為每個變數建立一個欄位,並為輸出建立一個欄位。每次程式碼改變數值時,就更新對應的欄位。

1.6 標準演算法:搜尋與排序

你需要理解這四個經典演算法是如何運作的。想像一下你有一疊亂序的試卷,你需要找到某位學生的試卷,或者按字母順序排列它們。

搜尋演算法

1. 線性搜尋(Linear Search): 你從頭到尾一個一個地查看列表中的每個項目。它適用於任何列表,但對於大型資料組來說速度很慢。
2. 二分搜尋(Binary Search): 快得多!你直接跳到列表的中間。如果你要找的項目比中間值小,就丟棄右半部分;如果更大,就丟棄左半部分。重複此過程直到找到為止。
重要事項: 二分搜尋適用於已經排序過的列表。

排序演算法

1. 氣泡排序(Bubble Sort): 你比較相鄰的兩個項目,如果順序不對就交換它們。你不斷地在列表中「循環掃描」,直到不需要再進行任何交換為止。
2. 合併排序(Merge Sort): 一種「分而治之」的演算法。你將列表拆分為單個項目,然後將它們按正確順序合併起來。這對於大型列表來說非常快!

記憶小撇步: 「線性(Linear)」就像一條線(line);「二分(Binary)」就像二分法(bi-secting,切成兩半)

1.7 演算法效率

我們如何知道一個演算法是否「好」?我們基於以下兩點評估其效率
時間: 需要多少次比較掃描
空間: 使用了多少記憶體

例子: 二分搜尋比線性搜尋更有效率,因為它通常只需更少的步驟就能找到答案。

關鍵總結: 不僅要找到解決方案,更要找到最快最簡潔的解決方案!