110 身心障礙特考三等 資訊處理 資料結構 考古題詳解

110 年・身心障礙特考・三等・資訊處理
試題代碼 資料結構

第 一 題

在大數據分析的應用中,許多資料集是以稀疏矩陣(Sparse matrix)的方式呈現,例如客戶的購物行為等。這些資料集共同的特性是資料維度大,但其中的資料量相對稀少。若直接以傳統陣列結構來儲存資料,將會造成大量的空間浪費。請以 C 語言完成下列問題要求:

(一) 設計一有效的二維稀疏矩陣資料結構,避免儲存不存在(或其值為 00)的資料,有效利用空間。(55 分)

(二) 使用所設計的資料結構,完成矩陣的轉置(Transpose)運算函式。(1010 分)

(三) 使用所設計的資料結構,完成維度分別為 m×nm\times n 的 AA 矩陣與 n×ln\times l 的 BB 矩陣之矩陣相乘(Multiply)運算函式。(1010 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

稀疏矩陣的非零元素遠少於所有元素的總數。若矩陣大小為 r×cr\times c、非零元素數為 tt,一般二維陣列需儲存 rcrc 個值;稀疏表示法只記錄非零元素及其座標,空間需求可降為 O(t)O(t)。

以下採用三元組表示法:每個非零元素記錄列索引、行索引和值。索引採 C 語言常見的 0 起算方式。矩陣相乘則以列鏈結串列儲存各列的非零元素,方便依列走訪及累加乘積。

解題方法

(一)稀疏矩陣資料結構

三元組中的 row、col 與題目慣用的「列、行」方向容易混淆,因此程式碼以 row 表示矩陣的列索引、col 表示行索引。

typedef struct {
 int row; // 列索引,0 起算
 int col; // 行索引,0 起算
 double value; // 非零值
} Term;

typedef struct {
 int rows; // 矩陣列數
 int cols; // 矩陣行數
 int terms; // 非零元素數
 Term *data; // 長度為 terms 的三元組陣列
} SparseMatrix;

data[k] 儲存一個非零元素及其座標。矩陣中值為 00 的元素不建立三元組,因此不占用儲存空間。三元組可依 (row, col) 排序;以下轉置程式會按列、行順序輸出結果。

(二)矩陣轉置

轉置會交換每個非零元素的列與行索引,並交換矩陣的列數與行數:

Ar,c=x⟹Ac,rT=xA_{r,c}=x \quad\Longrightarrow\quad A^T_{c,r}=x

以下採簡單的逐欄掃描:依原矩陣的欄索引 c 由小到大掃描全部三元組。每次找到該欄的元素,就交換其索引後寫入結果。這樣輸出的三元組會依新矩陣的列、行順序排列,時間複雜度為 O(cols×terms)O(cols\times terms)。

#include <stdlib.h>

int transpose(const SparseMatrix *src, SparseMatrix *dst)
{
 dst->rows = src->cols;
 dst->cols = src->rows;
 dst->terms = src->terms;
 dst->data = NULL;

 if (src->terms == 0)
 return 1;

 dst->data = malloc((size_t)src->terms * sizeof(Term));
 if (dst->data == NULL)
 return 0;

 int k = 0;
 for (int c = 0; c < src->cols; ++c) {
 for (int i = 0; i < src->terms; ++i) {
 if (src->data[i].col == c) {
 dst->data[k].row = src->data[i].col;
 dst->data[k].col = src->data[i].row;
 dst->data[k].value = src->data[i].value;
 ++k;
 }
 }
 }
 return 1;
}

呼叫成功後,dst->data 由呼叫端負責釋放;來源與目的矩陣應使用不同的結構,避免覆寫來源資料。

(三)矩陣相乘

令 AA 為 m×nm\times n 矩陣,BB 為 n×ln\times l 矩陣,則乘積 C=ABC=AB 的大小為 m×lm\times l,元素定義為:

Ci,j=∑k=0n−1Ai,kBk,jC_{i,j}=\sum_{k=0}^{n-1} A_{i,k}B_{k,j}

只有當 Ai,kA_{i,k} 與 Bk,jB_{k,j} 都是非零值時,才會對 Ci,jC_{i,j} 累加乘積。以下將三元組依列分組成鏈結串列,讓程式依序取得 AA 的第 ii 列,以及 BB 中列索引等於 kk 的元素。

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 二 題

【題組共用題幹】

一有向圖形(directed graph)G=(V,E)G=(V,E)如下圖所示,圖中包含節點 AA、BB、CC、DD、EE及各邊之權重。

(一) 請以相鄰矩陣(adjacency matrix)表達有向圖形 GG。(55 分)

(二) 設計一演算法找尋圖形中所有端點(node)對端點的最短路徑(all-pairs shortest path),並以有向圖形 GG的相鄰矩陣為例,說明所使用演算法的計算過程。(1515 分)

(三) 請說明在上述(二)中所使用演算法的時間複雜度(time complexity)為何?(55 分)

🖼️ 本題原卷含圖表。基於試題來源之版權考量,本站不轉載原卷影像; 題目文字已完整轉錄,圖表請自行參閱考選部公告之試題原檔。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考有向加權圖的相鄰矩陣,以及 Floyd–Warshall 全點對最短路徑演算法。相鄰矩陣的列代表出發點、欄代表到達點;若有邊,填入該邊權重,若無邊則填入 ∞\infty,對角線填 00。

解題方法

依圖中箭頭方向讀取邊,矩陣列、欄順序均採 A,B,C,D,EA,B,C,D,E。例如,A→BA\to B 權重為 88,所以第 AA 列、第 BB 欄填 88;反向的 B→AB\to A 權重為 77,因此第 BB 列、第 AA 欄填 77。

(一)相鄰矩陣

W=ABCDEA0848∞B70∞∞9C42052D4∞∞02E∞5750W= \begin{array}{c|ccccc} & A & B & C & D & E\\\hline A&0&8&4&8&\infty\\ B&7&0&\infty&\infty&9\\ C&4&2&0&5&2\\ D&4&\infty&\infty&0&2\\ E&\infty&5&7&5&0 \end{array}

此矩陣是加權有向圖的相鄰矩陣;WijW_{ij} 表示從節點 ii 到節點 jj 的直接邊權重。

(二)Floyd–Warshall 演算法

依序把 A,B,C,D,EA,B,C,D,E 當作中繼點。令 Dij(k)D^{(k)}_{ij} 表示只允許前 kk 個節點作為中繼點時,從 ii 到 jj 的最短距離,更新公式為:

Dij(k)=min⁡(Dij(k−1),  Dik(k−1)+Dkj(k−1))D^{(k)}_{ij} = \min\left(D^{(k-1)}_{ij},\; D^{(k-1)}_{ik}+D^{(k-1)}_{kj}\right)

每次更新都比較「目前距離」與「經過新中繼點的距離」,取較小值。計算結果如下,矩陣列、欄順序皆為 A,B,C,D,EA,B,C,D,E。

初始矩陣 D(0)=WD^{(0)}=W:

[0848∞70∞∞9420524∞∞02∞5750]\begin{bmatrix} 0&8&4&8&\infty\\ 7&0&\infty&\infty&9\\ 4&2&0&5&2\\ 4&\infty&\infty&0&2\\ \infty&5&7&5&0 \end{bmatrix}

以 AA 為中繼點後,B→CB\to C 更新為 7+4=117+4=11,B→DB\to D 更新為 7+8=157+8=15;D→BD\to B 更新為 4+8=124+8=12,D→CD\to C 更新為 4+4=84+4=8:

D(A)=[0848∞701115942052412802∞5750]D^{(A)}= \begin{bmatrix} 0&8&4&8&\infty\\ 7&0&11&15&9\\ 4&2&0&5&2\\ 4&12&8&0&2\\ \infty&5&7&5&0 \end{bmatrix}
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 三 題

對資料庫系統的檔案儲存結構而言,必須能夠隨著檔案資料的增多,動態新增儲存區塊(block)。例如:B-tree 樹狀檔案資料結構,即可隨著資料量變大而增加葉節點區塊(leaf node block),或增加樹的高度來因應。

下列為 m=5m=5(5-way)B-tree 的現況,目前已存有 1313 筆資料:

根節點包含:99、2020

其子節點依序包含:

  • 11、33、55
  • 1111、1414、1616、1818
  • 2222、2424、2626、2727

(一) 請問具有 KK 層以上、m=5m=5 結構的 B-tree 至少可以存放多少筆資料?(55 分)

(二) 請畫出完成運算 insert⁡(7)\operatorname{insert}(7) 與 insert⁡(28)\operatorname{insert}(28)後的 B-tree 結構。(1010 分)

(三) 完成上述(二)之後,接續畫出先後完成運算 insert⁡(15)\operatorname{insert}(15) 與 insert⁡(6)\operatorname{insert}(6)的 B-tree 結構。(1010 分)

🖼️ 本題原卷含圖表。基於試題來源之版權考量,本站不轉載原卷影像; 題目文字已完整轉錄,圖表請自行參閱考選部公告之試題原檔。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

m=5m=5 表示每個節點最多有 55 個子節點、最多存放 44 個鍵值。非根節點至少有 ⌈5/2⌉=3\lceil 5/2\rceil=3 個子節點,因此至少有 22 個鍵值;根節點至少有 11 個鍵值。節點鍵值超過上限時,將中間鍵值提升至父節點,並把節點分成左右兩個節點;若父節點也溢位,分裂會向上傳遞。

(一)KK 層以上的 B-tree 最少資料筆數

要讓樹具有至少 KK 層,採用每層節點數及鍵值數皆為最少的結構:

  • 根節點有 11 個鍵值,並至少有 22 個子節點。
  • 根的下一層有 22 個節點;之後每個非根內部節點至少有 33 個子節點。
  • 每個非根節點至少有 22 個鍵值。

因此,第 ii 層(根為第 11 層,i≥2i\ge 2)最少有 2⋅3i−22\cdot 3^{i-2} 個節點,各有 22 個鍵值。總筆數為

1+∑i=2K2⋅2⋅3i−2=1+4∑j=0K−23j=2⋅3K−1−1.1+\sum_{i=2}^{K} 2\cdot 2\cdot 3^{i-2} =1+4\sum_{j=0}^{K-2}3^j =2\cdot 3^{K-1}-1.

所以,具有 KK 層以上的 55-way B-tree 最少可存放

2⋅3K−1−1 筆資料\boxed{2\cdot 3^{K-1}-1\text{ 筆資料}}

(二)依序執行 insert⁡(7)\operatorname{insert}(7) 與 insert⁡(28)\operatorname{insert}(28)

初始根節點為 [9,20][9,20],三個子節點依序為 [1,3,5][1,3,5]、[11,14,16,18][11,14,16,18]、[22,24,26,27][22,24,26,27]。

插入 77 後,第一個葉節點成為 [1,3,5,7][1,3,5,7],未超過每個節點最多 44 個鍵值的限制。

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 四 題

霍夫曼碼(Huffman code)是具有最佳編碼的資料壓縮方法之一。今有下列訊息欲以霍夫曼碼編碼傳遞,以節省訊息量:

“PAPAYA_AND_BANANA_ARE_YUMMY”

其中空格「_」亦需計算在訊息量內。

(一) 請以該訊息詳述構建霍夫曼碼演算法的過程與結果。(2020 分)

(二) 依步驟說明所使用演算法的時間複雜度(time complexity)。(55 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

霍夫曼碼(Huffman code)是一種最佳前綴碼:任何一個字元的編碼都不是另一個字元編碼的前綴,因此解碼時不需要分隔符號。

建構時反覆選取目前頻率最低的兩個節點,合併成一個頻率為兩者總和的父節點,直到只剩一個根節點。由根走到葉節點的路徑形成該字元的碼字;每次向左記為 00,向右記為 11。低頻字元通常位於較深處,高頻字元則通常位於較淺處,以降低加權碼長。

解題方法

先計算訊息中每個字元的出現次數。訊息共有 2727 個字元,包含 4 個底線:

字元頻率
A8
_4
N3
Y3
M2
P2
B1
D1
E1
R1
U1

頻率總和為 2727。為使合併過程與碼字明確,以下遇到同頻節點時,以字元名稱及子樹內字元名稱的字典序決定先後;每次合併中,頻率較小者置左,並以左枝 00、右枝 11 記碼。霍夫曼碼遇到同頻節點時可以有不同的合併順序,因此碼字不唯一,但都能達到最佳加權碼長。

建構霍夫曼樹

依序合併兩個最低頻率的節點:

步驟合併節點新節點頻率
1B(1) 與 D(1)2
2E(1) 與 R(1)2
3U(1) 與 BD(2)3
4ER(2) 與 M(2)4
5P(2) 與 N(3)5
6Y(3) 與 UBD(3)6
7_(4) 與 ERM(4)8
8PN(5) 與 YUBD(6)11
9_(ERM)(8) 與 A(8)16
1011 與 1627

最後只剩頻率 2727 的根節點,建樹完成。沿樹由根至葉記錄 00、11,得到一組霍夫曼碼:

字元頻率霍夫曼碼
A811
_4100
N3001
Y310
M21011
P2000
B11110
D11111
E110100
R110101
U1110
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

其他考古題