113 年 國立臺灣大學生物機電系碩士班丁組《計算機概論(A)》
第 1 題10 分
Perform the binary subtraction operation of the two decimal signed integers -150 and -75 using two's complement representation. Show the step-by-step process in detail, including the conversion to two's complement, the subtraction, and any necessary adjustments.
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 二補數表示法(two's complement)
- 有號二進位整數的位元數選擇
- 以加法完成減法
- 溢位判斷與進位捨棄
二補數的形成方式為:
計算減法時,利用:
題目中的運算為:
由於 無法用 8 位元二補數表示,因此採用 9 位元。9 位元有號二補數的表示範圍為:
即:
因此 與 都能正確表示。
解題方法
將:
改寫為:
接著以 9 位元二補數進行運算。
一、將 轉為 9 位元二補數
先將 轉為二進位:
因此:
補成 9 位元:
逐位反相:
加 :
所以:
二、將 轉為 9 位元二補數
先將 轉為二進位:
因此:
補成 9 位元:
逐位反相:
加 :
所以:
三、將減法改為加法
原式為:
減去 ,等同於加上 的二補數。由於 的二補數就是 :
因此:
第 2 題10 分
Draw a deterministic finite automaton (DFA) diagram for the language accepting strings ending with 'abb' over input alphabets . Present the step-by-step process in detail.
登入後即可作答並保存紀錄。
此題考察確定性有限自動機 (DFA) 的設計,目標是辨識所有以 "abb" 結尾的字串。
核心觀念:
DFA 由一組狀態 (States)、輸入字母表 (Alphabet)、轉移函數 (Transition Function)、起始狀態 (Start State) 和終止狀態 (Accept States) 組成。DFA 的目標是讀取輸入字串,根據轉移函數在狀態間移動,若字串讀取完畢時,自動機停留在一個終止狀態,則該字串被接受。
設計 DFA 的關鍵在於如何定義狀態,使得每個狀態都能代表「到目前為止已讀取的字串,最長能匹配到目標結尾字串的哪個前綴」。
解題步驟:
-
定義目標字串和字母表:
- 目標結尾:
abb - 字母表
- 目標結尾:
-
識別可能的字串前綴:
我們需要設計狀態來記錄我們已經讀取了目標結尾abb的哪個前綴。- 空字串 (尚未讀取任何東西)
- 讀取到
a - 讀取到
ab - 讀取到
abb(目標結尾)
-
定義狀態:
基於上述前綴,我們可以定義以下狀態:- : 起始狀態。代表尚未讀取到
a,或者剛讀取的字串不構成a的前綴。 - : 代表剛讀取的字串以
a結尾。 - : 代表剛讀取的字串以
ab結尾。 - : 代表剛讀取的字串以
abb結尾。這是我們的終止狀態 (Accept State)。
- : 起始狀態。代表尚未讀取到
-
定義轉移函數 (Transition Function):
對於每個狀態和每個輸入字母,確定下一個狀態。-
從 (起始狀態):
- 如果讀到
a:我們成功匹配了目標結尾的第一個字元a,進入狀態 。
- 如果讀到
b:我們沒有匹配到a,而且讀到的b也無法構成任何目標前綴,所以我們仍然處於「未匹配」的狀態。我們可以維持在 (或者定義一個專門的「陷阱狀態」,但在此情況下,直接回到 更簡潔)。
- 如果讀到
-
從 (以
a結尾):- 如果讀到
a:我們現在以aa結尾。這依然可以視為以a結尾(因為aa的結尾是a)。所以我們保持在 。
- 如果讀到
b:我們現在以ab結尾。這正好是目標結尾的第二個前綴。進入狀態 。
- 如果讀到
-
從 (以
ab結尾):- 如果讀到
a:我們現在以aba結尾。這個字串的結尾是a,這符合 的定義。我們需要回到 。
- 如果讀到
b:我們現在以abb結尾。這正是我們的目標結尾!進入終止狀態 。
- 如果讀到
-
從 (以
abb結尾 - 終止狀態):- 如果讀到
a:我們現在以abba結尾。這個字串的結尾是a,這符合 的定義。我們需要回到 。
- 如果讀到
b:我們現在以abbb結尾。這個字串的結尾是bb。這個bb並不能直接構成abb的前綴,但b本身也不能構成a的前綴。我們需要仔細分析。
如果讀到abbb,它的結尾是b。這個b不能構成a的前綴,所以我們應該回到 。
- 如果讀到
-
-
確定起始狀態和終止狀態:
- 起始狀態:
- 終止狀態 (Accept States):
-
繪製 DFA 圖:
- 畫出四個節點,分別標記為 。
- 用一個箭頭指向 表示它是起始狀態。
- 用雙圓圈標記 表示它是終止狀態。
- 根據轉移函數繪製帶標籤的箭頭:
第 3 題10 分
Suppose the numbers are inserted in that order into an initially empty binary search tree. The binary search tree uses the usual ordering on natural numbers. What is the inorder traversal sequence of the resultant tree? Draw the resultant tree with your answer.
登入後即可作答並保存紀錄。
核心觀念
本題考查二元搜尋樹(Binary Search Tree, BST)的:
-
插入規則:
對每個新節點,若鍵值小於目前節點,往左子樹走;若鍵值大於目前節點,往右子樹走。 -
中序走訪(inorder traversal):
走訪順序為:對於使用通常大小關係的 BST,中序走訪結果必定是由小到大的排序序列。
解題方法
依序插入:
各節點的插入位置如下:
- :成為根節點。
- :插入 的左側。
- ,且 :插入 的左側。
- :插入 的右側。
- 、,但 :插入 的右側。
- ,但 :插入 的右側。
- 、、:插入 的左側。
- 、:插入 的右側。
- 、、、:插入 的右側。
- 、、、:插入 的左側。
第 4 題10 分
Insert the keys into the hash table of size 13. Resolve all collisions using double hashing technique. The first hash-function is , and the second hash-function is . Show the step-by-step process of how the keys are hashed and inserted, and indicate the resulting structure of the hash table after all insertions.
登入後即可作答並保存紀錄。
此題考察雜湊表 (Hash Table) 的建構,特別是使用雙重雜湊 (Double Hashing) 來處理碰撞 (Collision)。
核心觀念:
雜湊表是一種用於快速查找、插入和刪除鍵值對的資料結構。它使用雜湊函數將鍵映射到表格中的索引。當兩個不同的鍵映射到同一個索引時,就會發生碰撞。雙重雜湊是一種處理碰撞的方法,它使用第二個雜湊函數來計算探測序列 (Probe Sequence),以找到下一個可用的槽位。
對於雙重雜湊,當鍵 映射到索引 時,若該槽位已被佔用,則下一個探測的槽位為 ,其中 是雜湊表的大小, 是探測的次數(從 1 開始)。
解題步驟:
-
確定雜湊表參數:
- 雜湊表大小 。
- 第一個雜湊函數 。
- 第二個雜湊函數 。
- 要插入的鍵:。
-
初始化雜湊表:
雜湊表有 13 個槽位,初始時都是空的。我們用null或-表示空槽位。
Table: [-, -, -, -, -, -, -, -, -, -, -, -, -](索引 0 到 12) -
逐一插入鍵值:
-
插入 79:
- 槽位 1 是空的。
Table: [-, 79, -, -, -, -, -, -, -, -, -, -, -]
-
插入 69:
- 槽位 4 是空的。
Table: [-, 79, -, -, 69, -, -, -, -, -, -, -, -]
-
插入 98:
- 槽位 7 是空的。
Table: [-, 79, -, -, 69, -, -, 98, -, -, -, -, -]
-
插入 72:
- 槽位 7 已被 98 佔用。發生碰撞!
- 使用雙重雜湊處理:
- 計算
- 第一次探測 (): 新索引 =
新索引 = - 槽位 1 已被 79 佔用。再次碰撞!
- 第二次探測 (): 新索引 =
新索引 = - 槽位 8 是空的。插入 72。
- 計算
Table: [-, 79, -, -, 69, -, -, 98, 72, -, -, -, -]
-
插入 14:
- 槽位 1 已被 79 佔用。發生碰撞!
- 使用雙重雜湊處理:
- 計算
- 第一次探測 (): 新索引 =
新索引 = - 槽位 5 是空的。插入 14。
- 計算
Table: [-, 79, -, -, 69, 14, -, 98, 72, -, -, -, -]
-
插入 50:
- 槽位 11 是空的。
Table: [-, 79, -, -, 69, 14, -, 98, 72, -, -, 50, -]
-
-
最終雜湊表結構:
所有鍵都已插入。Table: [-, 79, -, -, 69, 14, -, 98, 72, -, -, 50, -]
第 5 題3 分
Suppose that in a group of 5 people: A, B, C, D, and E, the following pairs of people are acquainted with each other.
• A and C
• A and D
• B and C
• C and D
• C and E
a) Draw a graph G to represent this situation. (3%)
b) List the vertex set, and the edge set, using set notation. In other words, show sets V and E for the vertices and edges, respectively, in G = {V, E}. (4%)
c) Draw an adjacency matrix for G. (3%)
登入後即可作答並保存紀錄。
此題考察圖論 (Graph Theory) 的基本概念,包括圖的表示、頂點集合、邊集合以及鄰接矩陣。
核心觀念:
- 圖 (Graph): 由頂點 (Vertices) 和連接頂點的邊 (Edges) 組成。
- 無向圖 (Undirected Graph): 邊沒有方向。如果 A 和 B 之間有一條邊,則表示 A 和 B 之間有關係,這個關係對 A 和 B 來說是相同的。
- 鄰接矩陣 (Adjacency Matrix): 一種表示圖的方法,用一個方陣來表示頂點之間的連接關係。對於有 個頂點的圖,鄰接矩陣是一個 的矩陣 ,其中 如果頂點 和頂點 之間有邊,否則 。對於無向圖,鄰接矩陣是對稱的。
解題步驟:
a) 繪製圖 G:
-
確定頂點: 根據題目,有 5 個人:A, B, C, D, E。這些將是圖的頂點。
-
確定邊: 根據題目給出的「認識」關係,繪製邊。認識關係是雙向的,所以是無向圖。
- A 和 C 認識 在 A 和 C 之間畫一條線。
- A 和 D 認識 在 A 和 D 之間畫一條線。
- B 和 C 認識 在 B 和 C 之間畫一條線。
- C 和 D 認識 在 C 和 D 之間畫一條線。
- C 和 E 認識 在 C 和 E 之間畫一條線。
圖 G 的繪製:
頂點:A, B, C, D, E
邊:(A, C), (A, D), (B, C), (C, D), (C, E)A --- C --- E | \ / | | D | | / B一個更清晰的繪製方式:
graph TD A --- C A --- D B --- C C --- D C --- E A B C D E(請注意,上述 Mermaid 圖僅為示意,實際繪製時,請確保所有節點和邊都正確連接)
文字描述的圖:
頂點:A, B, C, D, E
邊:- A 連接到 C 和 D。
- B 連接到 C。
- C 連接到 A, B, D, E。
- D 連接到 A 和 C。
- E 連接到 C。
b) 列出頂點集合 V 和邊集合 E:
-
頂點集合 V: 包含圖中的所有頂點。
-
邊集合 E: 包含圖中的所有邊。邊的表示方式是頂點對,由於是無向圖,順序不重要,我們通常會按字母順序排列,或者使用集合表示 。
- A 和 C 認識
第 6 題10 分
Consider the following circuit. Assume that the input C is driven by a square wave signal with a 50% duty cycle. Draw a timing diagram that shows the waveforms at points A and B. Assume that the propagation delay through each gate is seconds.
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
核心觀念
圖中有一個反相器與兩個 NOR 閘,每個元件的傳播延遲皆為 。以下依電路位置假設:A 是下方 NOR 閘的輸出,B 是右側 NOR 閘的輸出。原圖未標出 A、B,若題目另有標示,需依實際測點對應。
下方 NOR 閘接收 與 ;右側 NOR 閘接收 與 。因此穩定時的邏輯關係為:
兩個 NOR 閘互相回授,輸出切換時間須逐級計入傳播延遲。
解題方法
設輸入方波週期為 ,半週期為 ,並假設 ,使輸出有時間完成切換。
以 上升緣發生於 為例:
- ** 上升:**右側 NOR 閘收到 ,經 後使 下降;接著下方 NOR 閘在 且 時輸出 ,再經 後使 上升。因此 於 下降, 於 上升。
第 7 題4 分
Given the following set of characters and their frequencies:
| Character | a | b | c | d | e |
|---|---|---|---|---|---|
| Frequency | 5 | 12 | 9 | 4 | 7 |
a) Construct a Huffman tree for the given set of characters based on their frequencies. (4%)
b) Determine the Huffman codes for each character in the set. (4%)
c) Encode the message "bee" using the Huffman codes obtained in part (b). (2%)
登入後即可作答並保存紀錄。
核心觀念
本題考查 Huffman coding(霍夫曼編碼),是一種根據字元出現頻率建立的最佳前綴碼。
主要原則如下:
- 頻率越高的字元,通常配置越短的編碼。
- 頻率越低的字元,通常配置越長的編碼。
- Huffman tree 的每個內部節點,其權重等於兩個子樹權重之和。
- 從根節點到葉節點的路徑決定字元編碼,約定左分支為 、右分支為 。
- Huffman code 具備 prefix-free property(前綴碼性質),任一字元的編碼不會是另一字元編碼的前綴,因此能夠唯一解碼。
解題方法
將所有字元依頻率由小到大排列:
每次取出頻率最小的兩個節點合併,產生新的內部節點,再將新節點放回排序集合中。
第一步:合併 與
產生節點 。
目前節點為:
第二步:合併 與
產生節點 。
目前節點為:
第三步:合併 與
產生節點 。
第四步:合併兩個子樹
根節點權重為 。
a) Huffman tree
約定左分支為 、右分支為 $1%,可建立下列 Huffman tree:
(37)
/ \
0 / \ 1
/ \
(16) (21)
/ \ / \
0 / \ 1 0 / \ 1
e:7 c:9 (da):9 b:12
/ \
0 / \ 1
d:4 a:5
其中:
- 根節點:
- 左子樹:
- 右子樹:
- 整體:$16+21=37
第 8 題10 分
Consider a hypothetical microcontroller with a simple assembly language. The microcontroller has three general-purpose registers: A, B, and C. The following instructions are supported:
• MOV A, #5: Move the immediate value 5 into register A.
• ADD B, A: Add the content of register A to register B.
• SUB C, B: Subtract the content of register B from register C.
• MUL B, C: Multiply the content of register C with register B.
• JMP 5: Jump to the instruction at address 5.
• HLT: Halt the microcontroller.
Assume the program counter (PC) starts at address 0. Write a simple assembly program that calculates the following expression:
Your program should store the final result in register C and then halt. (10%)
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 暫存器內容的保存與覆寫。
- 立即值(immediate value)的載入。
- 算術運算的運算元與結果存放位置。
- 程式計數器 PC 的順序執行與跳躍。
- 將
分成兩個因子後再相乘。
假設原始輸入分別存放於暫存器 與 ,最後結果必須存放於暫存器 。
解題方法
先計算兩個因子:
再計算:
若要完成此運算,指令集至少必須具備:
- 對 加上立即值 的能力;
- 對 減去立即值 的能力;
- 將 複製到 ;
- 令 乘以 。
例如,若補充下列常見指令:
ADD A, #5:SUB B, #3:MOV C, B:MUL C, A:
則程式如下:
; 原始 A、B 分別為輸入值
ADD A, #5 ; A = A + 5
SUB B, #3 ; B = B - 3
MOV C, B ; C = B - 3
MUL C, A ; C = (B - 3) × (A + 5)
HLT ; 停止
交換乘法因子的順序後,可得:
因此,程式結束時, 即為所求結果。
題面指令集的問題
依照題目列出的「支援指令」,無法嚴格寫出能計算任意 、 輸入值的合法程式,原因如下。
1. MOV A, #5 會覆寫原本的 A
題目唯一提供的立即值載入指令是:
MOV A, #5
執行後:
原本的 值會遺失,因此無法再計算原式中的 。
2. 沒有載入常數 3 的指令
題目沒有提供:
MOV B, #3
第 9 題5 分
Write a program in a programming language of your choice to perform operations on an integer array with n elements (n ≤ 100). Implement the following tasks using loops:
a) Find and print the maximum element and its index in the array. (5%)
b) Print the array in reverse order. (5%)
Ensure your program uses loops for array traversals and include comments to explain the logic of your code. The array and its values can be predefined within the program.
登入後即可作答並保存紀錄。
核心觀念
本題考查整數陣列的循序走訪與迴圈操作:
-
尋找最大值及其索引
- 逐一比較陣列元素。
- 使用變數
maxValue儲存目前最大值。 - 使用變數
maxIndex儲存最大值所在位置。 - 若出現相同最大值,以下程式保留第一次出現的位置。
- 索引採用常見的 0-based index,第一個元素索引為 。
-
反向輸出陣列
- 陣列最後一個元素索引為 。
- 使用迴圈令索引由 遞減至 。
陣列走訪的基本時間複雜度為 ,最多只需要額外使用固定數量的變數,因此空間複雜度為 。
解題方法
a) 找出最大元素及其索引
初始化:
接著從索引 開始逐一檢查:
便更新:
使用嚴格大於 >,可確保遇到相同最大值時保留第一次出現的位置。
b) 反向輸出
陣列共有 個元素,合法索引範圍為:
因此反向輸出時,迴圈從 開始,每次遞減 ,直到索引 。
參考程式碼(C++)
第 10 題10 分
Develop a program in a programming language of your choice to determine and display the prime factorization of a given positive integer. Prime factorization involves breaking down a number into its individual prime factors. Create a computer program that prompts the user to input a positive integer and then outputs its prime factorization. Make sure your program incorporates suitable loops and functions, and includes comments to elucidate the logic of your code. (10%)
Example output:
Enter a positive integer: 84
Prime Factorization of 84: 2 * 2 * 3 * 7
登入後即可作答並保存紀錄。
此題考察程式設計能力,要求開發一個程式來計算並顯示給定正整數的質因數分解 (Prime Factorization)。
核心觀念:
- 質因數分解 (Prime Factorization): 將一個合數 (composite number) 表示為一系列質數 (prime numbers) 的乘積。例如,。
- 質數 (Prime Number): 大於 1 的自然數,除了 1 和它本身以外不再有其他因數。
- 演算法:
- 從最小的質數 2 開始嘗試。
- 如果當前數字
n能被當前質數p整除,則將p加入質因數列表,並將n更新為n / p。重複此步驟,直到n不能再被p整除。 - 嘗試下一個質數。
- 如果嘗試到
p,且 ,則表示剩餘的n本身也是一個質數(如果 )。
- 程式結構:
- 需要一個主函數或入口點。
- 需要獲取使用者輸入。
- 需要一個核心函數來執行質因數分解。
- 需要將結果格式化並輸出。
- 建議使用迴圈和函數。
解題步驟:
-
選擇程式語言:
選擇 Python,因為其語法簡潔,適合快速實現。 -
設計質因數分解函數
prime_factorization(num):- 該函數接收一個正整數
num作為輸入。 - 初始化一個空列表
factors來儲存質因數。 - 處理因數 2:
- 使用
while num % 2 == 0:迴圈,只要num能被 2 整除,就將 2 加入factors,並更新num = num // 2。
- 使用
- 處理奇數因數:
- 從 3 開始,嘗試奇數作為可能的因數。
- 使用
for i in range(3, int(num**0.5) + 1, 2):迴圈。這裡的上限是num的平方根,因為如果num有一個大於其平方根的因數,那麼它必定也有一個小於其平方根的因數。步長為 2,因為我們已經處理了 2,之後只需要檢查奇數。 - 在迴圈內部,使用
while num % i == 0:迴圈,只要num能被i整除,就將i加入factors,並更新num = num // i。
- 處理最後的質因數:
- 如果在上述迴圈結束後,
num仍然大於 1,則說明剩餘的num本身是一個質數(且大於其原始平方根)。將這個剩餘的num加入factors。
- 如果在上述迴圈結束後,
- 返回
factors列表。
- 該函數接收一個正整數
-
編寫主程式邏輯:
- 提示使用者輸入一個正整數。
- 使用
input()獲取使用者輸入,並轉換為整數。 - 進行輸入驗證:確保輸入的是正整數。如果輸入無效,提示使用者重新輸入。
- 調用
prime_factorization()函數獲取質因數列表。 - 格式化輸出結果,將質因數用
*連接起來。
-
編寫 Python 程式碼:
import math
def prime_factorization(num):
"""
Calculates the prime factorization of a given positive integer.
Args:
num: A positive integer.
Returns:
A list of prime factors.
"""
factors = [] # Initialize an empty list to store prime factors
# Handle factor 2
# Keep dividing num by 2 as long as it's even
while num % 2 == 0:
factors.append(2)
num //= 2 # Use integer division
# Handle odd factors starting from 3
# We only need to check up to the square root of the remaining number
# We increment by 2 because we only need to check odd numbers
# The loop range goes up to int(sqrt(num)) + 1 to ensure the square root itself is checked if it's an integer
for i in range(3, int(math.sqrt(num)) + 1, 2):
# While i divides num, add i to factors and divide num by i
while num % i == 0:
factors.append(i)
num //= i
# If after all divisions, num is still greater than 1,
# it means the remaining num is a prime factor itself.
if num > 1:
factors.append(num)
return factors
def main():
"""
Main function to prompt user for input, perform prime factorization,
and display the result.
"""
while True:
try:
# Prompt the user to enter a positive integer
user_input = input("Enter a positive integer: ")
number = int(user_input)
# Validate the input: must be a positive integer
if number <= 0:
print("Invalid input. Please enter a positive integer greater than 0.")
elif number == 1:
print("Prime Factorization of 1: 1") # Special case for 1
break
else:
# Get the list of prime factors
prime_factors = prime_factorization(number)
# Format the output string
# Use ' * '.join() to connect the factors with '*'
# Convert each factor to string before joining
output_string = " * ".join(map(str, prime_factors))
# Display the result
print(f"Prime Factorization of {number}: {output_string}")
break # Exit the loop after successful execution
except ValueError:
# Handle cases where the input is not a valid integer
print("Invalid input. Please enter a valid integer.")
except Exception as e:
# Catch any other unexpected errors
print(f"An error occurred: {e}")
# Execute the main function when the script is run
if __name__ == "__main__":
main()
-
解釋程式碼邏輯 (Comments):
程式碼中已包含詳細的英文註解。中文解釋:
prime_factorization(num)函數:- 接收一個正整數
num。 - 初始化一個空列表
factors。 - 首先,檢查
num是否能被 2 整除。如果可以,將 2 加入factors,並用num //= 2更新num。重複此步驟直到num變成奇數。 - 然後,從 3 開始,以步長為 2(即只檢查奇數)遍歷到
num的平方根。對於每個奇數i,檢查它是否能整除當前的num。如果能,將i加入factors,並用num //= i更新num。重複此步驟直到num不能再被i整除。 - 最後,如果經過上述處理後
num仍然大於 1,說明剩餘的num本身就是一個質因數(例如,原始數字是 7,或者經過分解後剩下 13)。將這個num加入factors。 - 返回包含所有質因數的列表
factors。
- 接收一個正整數
main()函數:- 使用一個
while True迴圈來不斷提示使用者輸入,直到輸入有效。 try-except區塊用於處理可能的錯誤,如使用者輸入非數字。input()獲取字串輸入,int()轉換為整數。- 檢查輸入是否為正整數 (
number > 0)。 - 單獨處理數字 1 的情況,其質因數分解是 1。
- 如果輸入有效且大於 1,調用
prime_factorization()獲取因數列表。
- 使用一個