115 年 國立臺灣大學土木系碩士班電輔組《計算機程式》
第 1 題
Part I: 單選題 (共 10 題, 每一題 6%, 共 60%) ※ 本大題請於試卷內之「選擇題作答區」依序作答。
- 下列哪一個資料型態最適合用來存「是否通過 (True/False)」?
(A) int
(B) float
(C) bool
(D) str
登入後即可作答並保存紀錄。
本題考驗資料型態的選擇。在程式設計中,我們需要選擇最適合儲存特定類型資料的資料型態。
「是否通過」這個概念只有兩種可能:是或否,對或錯,真或假。這正是一個布林(Boolean)值的特性。
(A) int(整數):用於儲存整數值,例如 0, 1, -5, 100。雖然有時可以用 0 代表 False,1 代表 True,但這不是布林值的原生表示,且容易混淆。
(B) float(浮點數):用於儲存帶有小數點的數字,例如 3.14, -0.5。
第 2 題
- If a program must repeatedly process sensor data until a convergence criterion is satisfied, and the number of iterations is not known in advance, which control structure is MOST appropriate?
(A) for loop with a fixed range
(B) for loop over a predefined list
(C) while loop with a Boolean condition
(D) recursive function with a fixed depth
登入後即可作答並保存紀錄。
本題考驗在迭代次數未知的情況下,選擇最適合的迴圈結構。
題幹描述的場景是:程式需要重複處理感測器數據,直到滿足某個收斂條件 (convergence criterion) 為止。關鍵點在於「收斂條件」和「迭代次數未知」。
我們來分析各選項:
(A) for loop with a fixed range:這種迴圈(例如 for i in range(10):)執行固定次數。如果迭代次數未知,使用固定範圍的 for 迴圈就不適合,因為我們不知道應該設定多少次。
(B) for loop over a predefined list:這種迴圈(例如 for item in my_list:)會迭代列表中的每一個元素。如果我們不知道列表的長度,或者迭代的終止不是由列表長度決定的,這種迴圈也不適合。
第 3 題
- Which of the following data structures is FILO (First-In Last-Out)?
(A) Stack
(B) Queue
(C) Set
(D) Map
登入後即可作答並保存紀錄。
本題考驗對基本資料結構的理解,特別是其存取順序的特性。FILO 是 First-In Last-Out 的縮寫。
我們逐一分析選項:
(A) Stack(堆疊):堆疊是一種後進先出 (LIFO - Last-In, First-Out) 的資料結構。最後進入堆疊的元素會最先被取出。雖然題幹問的是 FILO,而堆疊是 LIFO,但這兩個術語在描述同一個概念:最後進來的先出去。例如,你疊盤子,最上面放的盤子會是第一個被拿走的。
(B) Queue(佇列):佇列是一種先進先出 (FIFO - First-In, First-Out) 的資料結構。
第 4 題
- A program needs to store an unknown number of data items at runtime, and the number may grow or shrink depending on user input. Which concept BEST addresses this requirement?
(A) Static memory allocation
(B) Compile-time array declaration
(C) Dynamic memory allocation
(D) Constant variables
登入後即可作答並保存紀錄。
本題考驗對記憶體配置方式的理解,以及如何處理執行時期大小不確定的資料儲存需求。
題幹描述的需求是:程式需要在執行時期 (runtime) 儲存數量未知的資料項目,且這個數量會根據使用者輸入而增減。
我們來分析各選項:
(A) Static memory allocation(靜態記憶體配置):這類記憶體(例如全域變數、區域變數在堆疊區)的大小在編譯時期就已確定,且在程式執行期間保持不變。這不適合儲存數量會變動的資料。
(B) Compile-time array declaration(編譯時期陣列宣告):在許多程式語言中,使用固定大小宣告的陣列(例如 C++ 中的 int arr[100];)是在編譯時期確定大小的。
第 5 題
- A large software system must be designed so that internal implementation details can change without affecting other components, as long as the external behavior remains the same. Which concept BEST supports this requirement?
(A) Global variables
(B) Encapsulation
(C) Hard-coded parameters
(D) Inline expansion
登入後即可作答並保存紀錄。
本題考驗軟體設計原則,特別是如何達成模組化和可維護性。題幹描述了一個重要的軟體設計目標:內部實現細節可以改變,而外部行為保持不變,這樣不會影響到系統的其他組件。
我們來分析各選項:
(A) Global variables(全域變數):全域變數使得程式的不同部分可以共享和修改同一個數據。這會導致組件之間高度耦合,一個組件對全域變數的修改可能會意外影響到其他組件,使得內部實現的改變難以隔離。這與題幹的要求背道而馳。
(B) Encapsulation(封裝):封裝是物件導向程式設計的核心概念之一。它將資料(屬性)和操作(方法)捆綁在一起,並隱藏對外部的實現細節,只暴露必要的接口。
第 6 題
- 下面 Python 程式會印出什麼?
s = "ABCDE"
print(s[1:4])
登入後即可作答並保存紀錄。
本題考驗 Python 字串的切片 (slicing) 操作。
Python 的字串切片語法是 string[start:stop:step]。
start是起始索引,包含該索引對應的字元。如果省略,則從字串開頭開始。stop是結束索引,不包含該索引對應的字元。如果省略,則直到字串結尾。step是步長,預設為 1。
在給定的程式碼中:
s = "ABCDE"
print(s[1:4])
第 7 題
- 下面 Python 程式最後 count 是多少?
count = 0
for i in range(1, 6):
if i % 2 == 0:
count += 1
登入後即可作答並保存紀錄。
本題考驗 Python 的 for 迴圈、range() 函數以及條件判斷。
程式碼逐行解釋:
count = 0: 初始化一個變數count,其值為 0。這個變數將用來計數。for i in range(1, 6):: 這是一個for迴圈。range(1, 6)函數會產生一個數字序列,從 1 開始,到 6 結束,但不包含 6。所以i會依序取值:1, 2, 3, 4, 5。
if i % 2 == 0:: 在迴圈的每一次迭代中,檢查當前變數i是否為偶數。%是模數 (modulo) 運算子,它會回傳除法的餘數。i % 2 == 0表示i除以 2 的餘數為 0,即i是偶數。
第 8 題
- Python 中, x = -7 // 2 的結果是?
(A) -3
(B) -3.5
(C) -4
(D) -2
登入後即可作答並保存紀錄。
本題考驗 Python 中的整數除法 (floor division) 運算子 //。
在 Python 中:
/是浮點數除法,即使兩個數都是整數,結果也可能是浮點數。例如7 / 2結果是3.5。//是整數除法(也稱為地板除法或向下取整除法)。它會將結果向下取整到最接近的整數。
對於正數,// 的行為與截斷 (truncation) 類似。例如 7 // 2 結果是 3。
第 9 題
- 下面 Python 程式會印出什麼?
A = [1, 2, 3]
B = A
B[0] = 99
print(A[0])
登入後即可作答並保存紀錄。
本題考驗 Python 中列表 (list) 的賦值行為,特別是關於傳遞參考 (pass-by-reference) 的概念。
程式碼逐行解釋:
A = [1, 2, 3]: 創建一個列表A,包含元素 1, 2, 3。在記憶體中,變數A儲存的是這個列表物件的記憶體位址。B = A: 將變數A的值(即列表物件的記憶體位址)賦值給變數B。這意味著A和B現在指向同一個列表物件。
第 10 題
- In Python, 若 d = {"a": 3, "b": 5},下列哪一行能取得 key "b" 對應的值?
(A) d["b"]
(B) d(b)
(C) d{b}
(D) d.get("c")
登入後即可作答並保存紀錄。
本題考驗 Python 字典 (dictionary) 的存取方式。
Python 的字典是一種儲存鍵值對 (key-value pairs) 的資料結構。
我們來分析各選項:
(A) d["b"]: 這是 Python 字典存取值的標準方法。使用方括號 [],裡面放入要查詢的鍵 (key)。如果鍵存在,則回傳對應的值;如果鍵不存在,則會引發 KeyError 錯誤。在這個例子中,"b" 是字典 d 中的一個鍵,對應的值是 5。所以 d["b"] 會正確地回傳 5。
(B) d(b): 圓括號 () 通常用於函數呼叫。將變數或鍵放在圓括號內用於字典存取是錯誤的語法。
第 1. (a) 題20 分
Part II: 程式與問答題 (共 2 題, 每一題 20%, 共 40%)
※ 本大題請於試卷內之「非選擇題作答區」標明題號依序作答。
- (20%) A simple linear search algorithm for an array works as follows: we first need to know the value we are seeking, which we refer to as the target. We can then perform a search by examining each array element using a loop and by testing whether the element matches the target. The search loop should be exited when the target value is found.
(a) Draw a flow chart to depict the above-mentioned algorithm, and (b) write a Python program to perform the linear search algorithm for an integer array.
登入後即可作答並保存紀錄。
本題要求繪製線性搜尋演算法的流程圖,並以 Python 程式實現。
核心觀念: 線性搜尋 (Linear Search) 是一種簡單的搜尋演算法,它依序檢查列表中的每一個元素,直到找到目標值或檢查完所有元素為止。
(a) 流程圖 (Flowchart)
流程圖使用標準的圖形符號來表示演算法的步驟:
- 起始/結束 (Terminator): 橢圓形,表示程式的開始或結束。
- 輸入/輸出 (Input/Output): 平行四邊形,表示讀取輸入或顯示輸出。
- 處理 (Process): 長方形,表示進行計算或資料處理。
- 判斷 (Decision): 菱形,表示一個條件判斷,有兩個或多個分支。
- 連接線 (Connector): 箭頭,表示流程的方向。
線性搜尋流程圖步驟:
- 開始 (Start)
- 輸入/讀取: 讀取要搜尋的陣列 (Array) 和目標值 (Target)。
- 初始化: 設定一個索引變數
index或i為 0。 - 迴圈開始判斷: 檢查
index是否小於陣列的長度。- 如果
index大於或等於陣列長度,表示已檢查完所有元素,目標未找到。
- 如果
- 元素比對: 取得陣列中
index位置的元素,並與Target進行比對。 - 判斷是否找到:
- 如果陣列元素等於
Target,表示找到目標。 - 如果陣列元素不等於
Target,則繼續搜尋下一個元素。
- 如果陣列元素等於
- 找到目標: 如果找到,則輸出「找到」,並結束。
- 未找到,繼續: 如果未找到,則將
index加 1,然後回到步驟 4 (迴圈開始判斷)。 - 檢查完畢,未找到: 如果迴圈結束(
index已達陣列長度),則輸出「未找到」,並結束。
流程圖繪製說明:
graph TD
A[開始] --> B[/讀取 Array, Target/];
B --> C[index = 0];
C --> D{index < Array.length?};
D -- Yes --> E[/Array[index]/];
E --> F{Array[index] == Target?};
F -- Yes --> G[/輸出 "Found"/];
G --> H[結束];
F -- No --> I[index = index + 1];
I --> D;
D -- No --> J[/輸出 "Not Found"/];
J --> H;
(b) Python 程式實現
第 2. (a) 題20 分
- (20%) A large language model like ChatGPT is very good at coding, but sometimes we need to spot the potential bugs. For example, a large language model generates the following Python code to compute the average value of a list of numbers.
def average(nums):
total = 0
for i in range(len(nums)):
total += nums[i]
return total / len(nums)
(a) Identify two potential problems or limitations in the above code and explain under what conditions these problems may occur. (b) Provide a corrected or improved version of the code.
登入後即可作答並保存紀錄。
本題要求找出一段 Python 程式碼中的潛在問題與限制,並提供修正或改進的版本。
程式碼分析:
這段程式碼的目的是計算一個數字列表的平均值。
def average(nums):定義了一個名為average的函數,接收一個列表nums。total = 0: 初始化一個變數total為 0,用於累加列表中的元素。for i in range(len(nums)):: 迴圈遍歷列表nums的索引。total += nums[i]: 將當前索引i對應的元素加到total中。return total / len(nums): 最後,用總和total除以列表的長度len(nums)來計算平均值並回傳。
(a) 潛在問題或限制 (Potential Problems or Limitations)
-
除以零的錯誤 (Division by Zero Error)
- 問題描述: 如果傳入的列表
nums是空的(即len(nums)為 0),則在最後的return total / len(nums)語句中會發生除以零的錯誤,導致程式崩潰。 - 發生條件: 當函數被呼叫時,傳入的
nums列表為空列表[]。 - 範例:
average([])會引發ZeroDivisionError。
- 問題描述: 如果傳入的列表
-
資料型態假設 (Data Type Assumption)
- 問題描述: 程式碼假設列表
nums中的所有元素都是數字(整數或浮點數),並且可以進行加法和除法運算。如果列表中包含非數字型態的元素(例如字串、None 等),在total += nums[i]這行就會引發TypeError。 - 發生條件: 當傳入的
nums列表中包含非數字型態的元素。 - 範例:
average([1, 2, "three"])會引發TypeError。
- 問題描述: 程式碼假設列表
-
浮點數精度問題 (Floating-Point Precision Issues) - (較少是「bug」,更多是「limitation」)
- 問題描述: 雖然不一定是 bug,但對於非常大或非常小的數字,或者需要極高精度的計算,浮點數運算可能存在精度損失。不過,對於一般的平均值計算,這通常不是主要問題。
- 發生條件: 處理極端數值或需要極高精度的場景。
我們主要關注前兩個更為直接和常見的「問題」。
(b) 修正或改進的版本 (Corrected or Improved Version)
為了處理上述問題,我們可以進行以下改進:
- 處理空列表: 在執行除法之前,檢查列表長度。如果為零,可以回傳一個特定的值(如 0、None)或引發一個更友善的錯誤訊息。
- 處理非數字元素: 可以選擇忽略非數字元素,或者引發錯誤。在此,我們選擇忽略它們,並只計算數字元素的平均值。如果列表不包含任何數字,則也需要處理。
改進後的程式碼: