110 司法特考三等 檢察事務官電子資訊組 程式語言 考古題詳解

110 年・司法特考・三等・檢察事務官電子資訊組
試題代碼 程式語言

第 一 題25 分

以下為 C++ 定義類別 Student 與 Class 的程式碼,請撰寫一「班級成績計算」的 C++ 程式。首先讓使用者輸入兩班學生(每班各有 3 位學生)的姓名與國文、英文、數學課的成績,並符合以下要求:

  • 為類別 Class 撰寫一建構元函式,將班上 3 位學生的國文、英文、數學成績、該班學生成績的平均分數與最高總分設為 0。
  • 為類別 Class 撰寫一方法 cal(),計算該班學生的平均分數。
  • 為類別 Class 撰寫一方法 findTop(),找出該班學生的最高總分與其所在位置。
  • 撰寫運算子 > 多載(overloading)功能,可以比較兩班的最高總分,並回傳哪一班的最高總分較高。
  • 撰寫主程式 main(),以驗證此程式的正確性。

類別 Student 與 Class 的程式碼如下:

class Student { //學生類別定義 public: string name; //學生姓名 int chn, eng, math; //學生國英數成績 };

class Class { //班級類別定義 public: Student student[3]; //每班 3 位學生 double avg; //該班學生的平均分數 int top, top_index; //該班學生的最高總分與其所在位置

public: Class(); //建構元函式將類別內變數初值設為 0 int operator>(Class &win); //定義運算子 > 的多載,以回傳最高總分班級 void cal(void); //計算該班學生的平均分數 void findTop(void); //找出該班學生的最高總分與其所在位置 };

程式執行範例如下:

第 1 班第 1 位學生名字:大明
請依序輸入他的國英數成績:85 66 92

第 1 班第 2 位學生名字:阿美
請依序輸入他的國英數成績:92 85 78

第 1 班第 3 位學生名字:小凱
請依序輸入他的國英數成績:96 92 90

第 2 班第 1 位學生名字:大雄
請依序輸入他的國英數成績:65 82 72

第 2 班第 2 位學生名字:阿吉
請依序輸入他的國英數成績:98 92 99

第 2 班第 3 位學生名字:小文
請依序輸入他的國英數成績:90 92 95

第 1 班平均成績:86.22
第 2 班平均成績:87.22
最高分在第 2 班是阿吉,總分為 289 分

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

這一題的完整詳解

核心觀念

本題考查 C++ 物件導向程式設計,重點包括:

  1. 類別與物件
  • Student 表示一位學生。
  • Class 表示一個班級,內含 3 個 Student 物件。
  1. 建構元函式
  • Class 用來初始化班級資料。
  • 將所有成績、平均分數、最高總分與最高分位置設為 00。
  1. 陣列成員
  • Student student[3] 表示每班有 3 位學生。
  • 陣列索引由 00 到 22。
  1. 成員函式
  • cal 計算班級平均分數。
  • findTop 找出最高總分及學生位置。
  1. 運算子多載
  • 以 operator> 比較兩班的最高總分。
  • 回傳第 1 班、第 2 班,平手時回傳 00。

解題方法

一、平均分數計算

每位學生有國文、英文、數學三科成績,因此全班共有 3×3=93 \times 3=9 個科目成績。

班級平均分數為:

平均分數=∑i=02(chni+engi+mathi)9\text{平均分數} = \frac{\displaystyle\sum_{i=0}^{2} (\text{chn}_i+\text{eng}_i+\text{math}_i)}{9}

也可以先求每位學生的總分,再將 3 位學生總分相加後除以 99。

二、最高總分計算

每位學生總分為:

總分i=chni+engi+mathi\text{總分}_i = \text{chn}_i+\text{eng}_i+\text{math}_i

依序比較 3 位學生的總分:

  • 若目前學生總分高於 top,更新 top。
  • 同時將其位置記錄到 top_index。
  • 程式內部使用 00 起始索引,輸出時再加 11 轉成人類習慣的第 1 位、第 2 位、第 3 位。

三、兩班最高總分比較

呼叫:

int winner = class1 > class2;

定義如下:

  • 第 1 班最高總分較高,回傳 1。
  • 第 2 班最高總分較高,回傳 2。
  • 兩班相同,回傳 0。

必須先執行兩班的 findTop,才能正確比較 top。


完整 C++ 程式

🔒

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

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

免費註冊

第 二 題25 分

(一)變數的種類可概分為區域變數(Local Variable)、全域變數(Global Variable)與靜態變數(Static Variable),請就宣告方式、有效範圍(Scope)、程式碼維護比較其差異。(15 分)

(二)遞迴函式(Recursive Function)通常也可以改用迴圈(Loop)方式來撰寫,請就程式碼撰寫難易度、理解性、執行效能、記憶體使用比較其差異。(10 分)

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

這一題的完整詳解

核心觀念

本題考查兩組程式設計基礎觀念:

  1. 變數的分類與作用域管理:
  • 區域變數(Local Variable)
  • 全域變數(Global Variable)
  • 靜態變數(Static Variable)
  1. 遞迴函式與迴圈的程式實作比較:
  • 程式碼撰寫難易度
  • 程式理解性
  • 執行效能
  • 記憶體使用量

以下以 C/C++ 常見語意說明。不同程式語言對 static 的細節定義不同,作答時應掌握「作用域」與「生命週期」兩個核心概念。


(一)區域變數、全域變數與靜態變數比較

1. 區域變數(Local Variable)

宣告方式

在函式、區塊或迴圈內宣告的變數,通常就是區域變數。

void func {
 int x = 10; // 區域變數
}

若在某個區塊中宣告,其作用範圍通常限於該區塊:

void func {
 if (condition) {
 int y = 20;
 printf("%d", y);
 }

 // y 在此處不可使用
}

有效範圍(Scope)

區域變數只能在宣告它的函式或區塊內使用,離開該範圍後便不可直接存取。

void func {
 int x = 10;
 printf("%d", x); // 正確
}

void other {
 printf("%d", x); // 錯誤,x 不在此函式的作用域內
}

區域變數具有封裝性,其他函式無法直接修改其內容。

生命週期

一般區域變數通常具有自動儲存期:

  • 進入函式或區塊時建立。
  • 離開函式或區塊時消失。
  • 每次重新進入函式時,通常會重新建立並初始化。

程式碼維護

優點如下:

  • 變數使用範圍小,容易追蹤資料流向。
  • 不同函式可以使用相同變數名稱,不易互相干擾。
  • 降低函式之間的耦合程度。
  • 修改某一函式時,較不容易影響其他程式區域。

缺點是:

  • 若多個函式都需要相同資料,必須透過參數傳遞或回傳值交換資料。
  • 不適合保存跨函式呼叫仍須保留的狀態。

2. 全域變數(Global Variable)

宣告方式

在所有函式之外宣告的變數,通常屬於全域變數。

int count = 0; // 全域變數

void add {
 count++;
}

void print {
 printf("%d", count);
}

若跨檔案使用,通常會在其他檔案使用 extern 宣告:

extern int count;

有效範圍(Scope)

全域變數的作用域通常自宣告位置開始,延伸到該原始檔案的結尾。若搭配 extern,可供其他原始檔案使用。

在單一檔案中,函式通常都可以存取同一個全域變數:

int value = 5;

void func1 {
 value = 10;
}

void func2 {
 printf("%d", value);
}

生命週期

全域變數通常具有整個程式執行期間的生命週期:

  • 程式開始執行時配置。
  • 程式結束時釋放。
  • 若未明確初始化,通常會自動初始化為零值。

程式碼維護

優點如下:

  • 多個函式可以直接共用資料。
  • 適合表示整個程式共用的設定值、狀態或資源。

缺點如下:

  • 任何可見的函式都可能修改它,資料流向不易追蹤。
  • 形成函式之間的高度耦合。
  • 修改一處全域變數,可能造成多個模組行為改變。
  • 不利於模組化、測試及除錯。
  • 在多執行緒程式中,若缺乏同步控制,可能產生競爭條件。
  • 名稱容易與區域變數衝突,增加閱讀困難。

因此,除非確實需要整個程式共用,通常應優先使用區域變數、參數傳遞或封裝於物件中的成員變數。


3. 靜態變數(Static Variable)

static 的意義必須同時從「作用域」及「生命週期」判斷。在 C/C++ 中,靜態變數常見於兩種形式。


(1)函式內的靜態區域變數

void counter {
 static int count = 0;
 count++;
 printf("%d\n", count);
}

若連續呼叫:

counter; // 1
counter; // 2
counter; // 3

作用域

函式內的 static 變數仍然只有函式內可直接使用,因此其作用域與區域變數相近。

生命週期

與一般區域變數不同,函式內的靜態變數:

  • 程式啟動時配置。
  • 整個程式執行期間持續存在。
  • 函式結束後不會消失。
  • 再次進入函式時保留上次的值。
  • 通常只在第一次執行宣告處時初始化。

因此,函式內靜態變數可視為「具有區域作用域、全程生命週期」的變數。


(2)檔案層級的靜態變數

static int file_count = 0;

此變數宣告於所有函式之外,但加上 static 後:

  • 生命週期仍為整個程式執行期間。
  • 作用域限制在目前的原始檔案。
  • 其他原始檔案無法透過 extern 直接存取。

這種語法常用於實作檔案內部資料,避免名稱暴露給其他模組。


4. 綜合比較表

比較項目區域變數全域變數靜態變數
常見宣告位置函式或區塊內所有函式之外函式內或檔案層級,搭配 static
作用域函式或區塊內通常可跨函式,亦可跨檔案函式內靜態變數限於函式;檔案層級靜態變數限於該檔案
生命週期進入區塊建立,離開區塊消失整個程式執行期間整個程式執行期間
函式結束後資料是否保留否是是
是否容易被其他模組修改不容易容易檔案層級靜態變數不易;函式內靜態變數只能透過函式操作
封裝性高低通常高於全域變數
適用情況暫時性計算、函式內部資料多個模組確實共用的狀態保存函式狀態、隱藏檔案內部資料
維護性最佳較差通常優於全域變數

5. 程式碼維護的比較與結論

維護性通常可作如下排序:

適當使用區域變數>適當使用靜態變數>大量使用全域變數\text{適當使用區域變數} > \text{適當使用靜態變數} > \text{大量使用全域變數}

區域變數的影響範圍最小,最容易進行模組化與測試。靜態變數能限制外部存取範圍,但因為生命週期很長,仍可能造成隱藏狀態,使函式不再完全依賴輸入參數。全域變數雖然使用方便,卻會增加耦合與除錯困難。


(二)遞迴函式與迴圈比較

1. 遞迴函式的核心概念

遞迴函式是指函式在執行過程中直接或間接呼叫自己。

遞迴必須具備兩個要素:

  1. 基底條件(Base Case):決定何時停止遞迴。
  2. 遞迴步驟(Recursive Case):將問題化為規模較小的相同問題。

例如計算階乘:

int factorial(int n) {
 if (n == 0) {
 return 1; // 基底條件
 }
 return n * factorial(n - 1); // 遞迴步驟
}

其數學定義為:

🔒

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

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

免費註冊

第 三 題25 分

請使用 C/C++、Java 或 Python 任一程式語言,撰寫一支加密演算法程式,讓使用者輸入一語句,然後將語句中的每個大小寫字母轉換成其反序的字母(A↔ZA\leftrightarrow Z、B↔YB\leftrightarrow Y、C↔XC\leftrightarrow X、…\ldots、x↔cx\leftrightarrow c、y↔by\leftrightarrow b、z↔az\leftrightarrow a)。

若所輸入的語句中有不是英文字母的字元,則以原字元輸出。

例如:

所輸入的語句為「abcd6ZYXW」,則輸出應為「zyxw6ABCD」,則輸出應為「zyxw6ABCD」。

所輸入的語句為「R olev blf!」,則輸出應為「I love you!」。(25 分)

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

這一題的完整詳解

核心觀念

本題考查「逐字元處理」與英文字母的反序替換,也稱為 Atbash substitution。

英文字母共有 26 個,將字母編號如下:

  • 大寫:A=0, B=1,…, Z=25A=0,\ B=1,\ldots,\ Z=25
  • 小寫:a=0, b=1,…, z=25a=0,\ b=1,\ldots,\ z=25

反序字母的編號為:

新編號=25−原編號\text{新編號}=25-\text{原編號}

因此:

  • 大寫字母範圍為 A 至 Z
  • 小寫字母範圍為 a 至 z
  • 非英文字母,例如空白、數字、標點符號,必須原樣輸出

例如大寫字母 C:

C=2,25−2=23,23=XC=2,\qquad 25-2=23,\qquad 23=X

所以 C 轉換為 X。

解題方法

讀入整行語句,從左至右逐一檢查每個字元:

  1. 若字元介於 A 與 Z 之間,依大寫字母公式轉換。
  2. 若字元介於 a 與 z 之間,依小寫字母公式轉換。
  3. 其餘字元直接保留。
  4. 將所有轉換後的字元依原順序連接並輸出。

大寫字母的轉換公式為:

新字元=chr⁡(ord⁡(′A′)+25−(ord⁡(c)−ord⁡(′A′)))\text{新字元} = \operatorname{chr}\left( \operatorname{ord}('A')+ 25-\left(\operatorname{ord}(c)-\operatorname{ord}('A')\right) \right)

小寫字母的轉換公式為:

新字元=chr⁡(ord⁡(′a′)+25−(ord⁡(c)−ord⁡(′a′)))\text{新字元} = \operatorname{chr}\left( \operatorname{ord}('a')+ 25-\left(\operatorname{ord}(c)-\operatorname{ord}('a')\right) \right)

其中:

  • ord(c):取得字元的數值編碼
  • chr(n):將數值編碼轉回字元

Python 參考程式

🔒

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

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

免費註冊

第 四 題25 分

中華民國的身分證字號共有 10 個字元,其編碼原則如下:

第一個字元為大寫的英文字母,代表出生地區;其餘 9 個字元皆為數字。

在套用編碼原則時,第一個大寫英文字母須先依下表轉換為數字:

字母:A B C D E F G H I J K L M
數字:10 11 12 13 14 15 16 17 34 18 19 20 21

字母:N O P Q R S T U V W X Y Z
數字:22 35 23 24 25 26 27 28 29 32 30 31 33

轉換後的身分證字號共有 11 位數字,每一位數字均有固定的權重(Weight),由左往右依序為:

1,9,8,7,6,5,4,3,2,1,11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1

判斷身分證字號是否正確的方法為:各位數字與其相對應的權重相乘後再加總。加總後的結果若為 10 的倍數,則該身分證字號即屬有效。

請使用 C/C++、Java 或 Python 任一程式語言,撰寫一支中華民國身分證字號的驗證程式。

例如:

所輸入的身分證字號為「A123456789」,則輸出應為「A123456789 為有效的身分證字號」。

所輸入的身分證字號為「Z987654321」,則輸出應為「Z987654321 為無效的身分證字號」。(25 分)

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

這一題的完整詳解

核心觀念

本題考查:

  1. 身分證字號格式判斷。
  2. 英文字母轉換為兩位數字。
  3. 加權總和驗證法。
  4. 字串處理與迴圈運算。

依題目規則,身分證字號原本為:

  • 第 1 碼:大寫英文字母。
  • 第 2 至第 10 碼:數字。

英文字母轉換後,會產生兩位數字,因此共形成 11 位數字,再搭配權重:

1,9,8,7,6,5,4,3,2,1,11,9,8,7,6,5,4,3,2,1,1

將各位數字與對應權重相乘後加總,若總和為 1010 的倍數,即為有效身分證字號。

本題屬程式設計題,沒有涉及法條適用問題。

解題方法

一、先檢查輸入格式

輸入字串必須符合:

  • 長度為 10。
  • 第 1 個字元為 A 至 Z 的大寫英文字母。
  • 第 2 至第 10 個字元全部為數字。

格式不符時,直接判定為無效。

二、將英文字母轉為兩位數字

建立英文字母與數字的對照表,例如:

  • A 對應 10
  • B 對應 11
  • I 對應 34
  • Z 對應 33

若輸入為 A123456789,英文字母 A 轉換為 10,所以完整數字序列為:

1,0,1,2,3,4,5,6,7,8,91,0,1,2,3,4,5,6,7,8,9

三、進行加權計算

將上述數字依序乘上權重:

S=1×1+0×9+1×8+2×7+3×6+4×5+5×4+6×3+7×2+8×1+9×1\begin{aligned} S={}&1\times1+0\times9+1\times8+2\times7+3\times6\\ &+4\times5+5\times4+6\times3+7\times2+8\times1+9\times1 \end{aligned}

因此:

S=130S=130

因為 130130 是 1010 的倍數,所以 A123456789 為有效身分證字號。

若:

S mod 10=0S\bmod 10=0

則判定有效;否則判定無效。

Python 參考程式

🔒

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

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

免費註冊

其他考古題