114 年 國立高雄大學資訊工程學系碩士班《離散數學與資料結構》
第 1 題
Each of the one million car license plates labeled from 000000 to 999999 can be denoted as , where for .
(a) In how many of these car licenses are all the six digits distinct? (3%)
(b) In how many of these car licenses are the six digits in the relationship ? (3%)
(c) In how many of these car licenses are the six digits in the relationship ? (3%)
(d) In how many of these car licenses does the digit 2 appear? (3%)
(e) In how many of these car licenses does at least one of the digits 0, 1, and 2 appear? (3%)
(f) In how many of these car licenses does at least two of the digits 0, 1, and 2 appear? (6%)
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 乘法原理與排列:
- 組合:
- 重複組合:
- 補集原理
- 容斥概念與分類計數
車牌允許以 開頭,因此六位數字的總數為
(a) 六個數字皆相異
六個位置依序選取不同數字:
- 第 1 位: 種
- 第 2 位: 種
- 第 3 位: 種
- 第 4 位: 種
- 第 5 位: 種
- 第 6 位: 種
因此
(b) 六個數字嚴格遞增
條件為
先從 至 的十個數字中選出六個,再按照遞增順序排列。選定數字後,排列方式唯一,因此
(c) 六個數字非遞減
條件為
此時數字可以重複。問題等同於從 種數字中選取 個,允許重複且不計順序,使用重複組合公式:
(d) 至少出現一次數字
使用補集原理。
全部車牌數:
完全不出現數字 時,每個位置有 種選擇,因此共有
所以至少出現一次數字 的車牌數為
(e) 至少出現一個數字
先計算完全不出現 的車牌。每個位置只能使用
共 種數字,因此有
張車牌。
第 2 題9 分
For a set of three distinct numbers, we can order them as where is the middle, is the smallest, and is the largest. From this hint, give a combinatorial proof that
登入後即可作答並保存紀錄。
核心觀念
本題考查「雙重計數法」:對同一個集合,用兩種不同方式計算其元素個數。
右式
表示從集合
中選出三個相異元素的方式數。選出的三個數必可唯一排列為
固定中間數 後:
- 比 小的數有 個,可選作 ;
- 比 大的數有 個,可選作 。
因此固定 時共有
組三元素集合。
解題方法:以中間數分類
考慮集合
中所有三個相異元素的子集合。
直接選取三個元素,總數為
接著按照三元素中的中間數 分類。
由於必須有一個數小於 、一個數大於 ,所以
當中間數固定為 時:
共有 種選法;而
共有 種選法。因此此類別共有
種。
將所有可能的中間數加總:
令
則當 時 ,當 時 ,且
所以
展開即得
第 3 題5 分
Given two sentences below:
- "Mary is much quicker than John."
- "John is slightly quicker than Mary."
Which data structure is most appropriate to store and analyze the grammatical components (e.g., subject, verb, modifier, adjective, comparison)?
(a) Stack
(b) Queue
(c) Dictionary
(d) Linked List
登入後即可作答並保存紀錄。
核心觀念
本題考查資料結構的用途,以及如何表示「語法成分與其內容」之間的對應關係。
句子可拆解為:
- 主詞(subject):Mary、John
- 動詞(verb):is
- 程度修飾語(modifier):much、slightly
- 形容詞(adjective):quicker
- 比較結構(comparison):than John、than Mary
這些資料具有明確的「欄位名稱 → 對應內容」關係,例如:
最適合此種「依照鍵值快速尋找資料」需求的資料結構是 Dictionary(字典、映射表)。
解題方法
判斷資料結構時,先觀察資料的主要操作方式。
本題不是要求按照先進後出順序處理資料,也不是要求按照先進先出順序排隊,更不是單純處理節點的線性串接,而是要將不同語法角色對應到各自的內容。因此可使用下列形式表示:
{
subject: "Mary",
verb: "is",
modifier: "much",
adjective: "quicker",
comparison: "than John"
}
第二句則可表示為:
{
subject: "John",
verb: "is",
modifier: "slightly",
adjective: "quicker",
comparison: "than Mary"
}
其中:
subject、verb、modifier等是鍵(key)。Mary、is、much等是值(value)。- 可透過鍵直接取得指定的語法成分。
因此,Dictionary 最能符合題目所說的「儲存並分析語法組成」。
選項分析
(a) Stack
Stack 採用後進先出(Last In, First Out, LIFO)原則,主要操作包括:
push:將資料放入堆疊頂端。pop:取出最上方資料。
Stack 適合處理函式呼叫、括號匹配、深度優先搜尋及復原操作等具有「最近加入的資料先處理」特性的問題。
第 4 題5 分
What is the main advantage of using a double hashing technique in hash tables?
(a) It allows for dynamic resizing of the hash table.
(b) It reduces the clustering problem in open addressing.
(c) It ensures keys are stored in sorted order.
(d) It makes the insertion operation O(1) in all cases.
登入後即可作答並保存紀錄。
核心觀念
本題考查雜湊表(hash table)在「開放定址法」(open addressing)中的碰撞處理,以及 double hashing 對叢集問題(clustering)的改善效果。
當兩個鍵值經由雜湊函數得到相同位置時,就會發生碰撞。開放定址法不使用鏈結串列,而是在表格內尋找其他空位。常見探測方法包括:
- 線性探測(linear probing)
- 二次探測(quadratic probing)
- 雙重雜湊(double hashing)
雙重雜湊通常使用下列探測公式:
其中:
- :待插入或搜尋的鍵值
- :第一次雜湊所得到的起始位置
- :決定探測步長的第二個雜湊函數
- :第 次探測
- :雜湊表大小
與線性探測固定以相同步長逐格尋找不同,雙重雜湊會依照鍵值產生不同的探測步長,因此不同鍵值即使發生碰撞,也較不容易走過相同的探測路徑。
解題方法
判斷各選項是否為 double hashing 的主要優點即可。
線性探測的探測位置通常為:
當連續位置逐漸被占用時,容易形成一長段連續的已使用區域,稱為主要叢集(primary clustering)。後續發生碰撞的鍵值容易加入同一區域,使叢集越來越大,降低搜尋效率。
雙重雜湊使用第二個雜湊函數決定步長:
不同鍵值通常會得到不同的 ,探測序列因此較分散,可有效降低開放定址法中的 clustering 問題。
必須注意,雙重雜湊主要是「降低」叢集,不是保證完全消除所有碰撞,也不會保證所有操作在任何情況下都是 。
選項分析
(a) It allows for dynamic resizing of the hash table.
第 5 題5 分
Given a binary tree with nodes, you want to find the maximum sum of values from the root to any leaf. Which of the following approaches is the most efficient?
(a) Depth-First Search with recursion, using space for the call stack.
(b) Breadth-First Search using a queue, with time complexity .
(c) Dynamic programming with bottom-up traversal, using space and time.
(d) Pre-order traversal using a stack, with time complexity .
登入後即可作答並保存紀錄。
觀念說明
求解二元樹從根節點至葉節點的最大路徑和(Maximum Root-to-Leaf Path Sum),最佳策略為使用動態規劃(Dynamic Programming)配合自底向上(Bottom-up,即後序遍歷 Post-order Traversal)。
定義 為以節點 為根之子樹中,從 到葉節點的最大路徑總和,狀態轉移方程為:
第 6 題
You are tasked with storing and searching a set of vectors efficiently. Suppose you have vectors, each of size . You need to design a system for efficient storage and retrieval of these vectors.
(a) Propose a data structure to store the vectors, ensuring fast access by a unique identifier for each vector. (10%)
(b) Describe an algorithm to find the vector most similar to a given query vector using cosine similarity. (10%)
(c) Analyze the time complexity of your search algorithm. (10%)
登入後即可作答並保存紀錄。
核心觀念
本題考查三個重點:
- 使用適當的資料結構,依唯一識別碼快速取得向量。
- 利用 cosine similarity 衡量兩個向量的方向相似程度。
- 分析逐一比較所有向量時的時間複雜度。
設資料庫中的第 個向量為
查詢向量為
兩向量的 cosine similarity 定義為
其中內積與向量長度分別為
以及
cosine similarity 越大,表示兩向量方向越接近;若向量皆為非零向量,其值介於 與 之間。
解題方法
(a)向量儲存資料結構
可使用「雜湊表搭配向量陣列」:
例如:
HashTable
"V0001" → vectors[0]
"V0002" → vectors[1]
"V0003" → vectors[2]
其中:
vectorID是每個向量的唯一識別碼。vectors可使用連續陣列儲存所有 個 維向量。- 雜湊表負責由識別碼快速找到向量位置。
- 向量本身可使用浮點數陣列儲存,例如
float[128]。
若雜湊函數分布良好,依照唯一識別碼查詢的平均時間複雜度為
因此,此設計同時具備:
- 依 ID 快速存取;
- 向量資料排列集中,便於連續掃描;
- 可預先儲存向量長度,避免每次搜尋重複計算。
每個向量可額外儲存其平方長度:
搜尋時再取平方根,或直接利用正規化向量進行比較。
(b)使用 cosine similarity 搜尋最相似向量
採用精確線性搜尋:對資料庫中的每個向量計算 cosine similarity,保留相似度最大的向量。
步驟一:計算查詢向量長度
若 為零向量,則 cosine similarity 無定義,必須先拒絕該查詢或另行指定處理規則。本題假設查詢向量不是零向量。
步驟二:逐一計算相似度
對每個資料庫向量 :
-
計算內積:
-
計算或讀取 。
-
計算:
-
若 大於目前最大相似度,更新最佳答案。
伪程式如下:
第 7 題
Given the following set of C codes:
#include <stdio.h>
#include <string.h>
void encode(const char* input, char* output) {
int i = 0, j = 0;
while (input[i] != '\0') {
char current = input[i];
int count = 1;
while (input[i] == input[i + 1]) {
count++;
i++;
}
output[j++] = current;
output[j++] = count + '0'; // Works for single-digit counts
i++;
}
output[j] = '\0'; // Null-terminate
}
int main() {
char input[] = "aaabbccccdaa";
char output[50]; // Fixed size array for output
encode(input, output);
printf("Original: %s\n", input);
printf("Encoded: %s\n", output);
return 0;
}
(a) Please identify any errors in the provided code. (10%)
(b) If errors are present, what is the output after correcting them? (10%)
(c) Describe the objective that this set of codes aims to achieve. (5%)
登入後即可作答並保存紀錄。
(a) 程式碼錯誤與潛在問題分析
- 無法處理重複次數大於等於 10 的字元(邏輯缺陷):
程式中使用output[j++] = count + '0';將計數寫入輸出陣列。該寫法僅適用於單數位計數()。若連續字元重複次數 ,如 時, 會得到 ASCII 碼的':'而非字串"10",導致編碼結果錯誤。 - 缺乏輸出緩衝區邊界檢查(安全隱患):
encode函式未傳入output陣列的容量限制,若編碼後的字串長度超過output分配空間(本例為 50 bytes),會引發緩衝區溢位(Buffer Overflow)。
(b) 修正後的執行結果
修正多位數計數問題(如改用 sprintf 寫入數字)後,對輸入字串 "aaabbccccdaa" 進行游程統計:
'a'重複 3 次"a3"'b'重複 2 次"b2"'c'重複 4 次"c4"