108 地方特考四等 資訊處理 程式設計概要 考古題詳解
第 一 題15 分
以下 Java 程式執行後,螢幕會顯示什麼?
public class Problem1 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 1; j <= i; j++) System.out.print(' ');
for (int j = 1; j <= 6 - i; j++)
System.out.print("**");
System.out.println();
}
}
}
登入後即可作答並保存紀錄。
核心觀念
本題測驗的核心為 Java 巢狀迴圈(Nested Loops)之控制流程與圖形輸出追蹤,主要評量以下重點:
- 迴圈計數與終止條件:評量對計數型
for迴圈初值、條件判斷式(<=)、步進值(++)之掌握。 - 輸出方法之差異:
System.out.print:輸出資料後不換行,後續輸出接續於同一列後方。System.out.println:輸出資料(此處為空白)並執行換行(Line Break)。
- 字元與字串輸出特性:注意第一組內層迴圈輸出單一空格字元
' ',第二組內層迴圈每次印出雙星號字串"**"。
解題方法
解析此類圖形列印題,最穩健且標準的切入點為「建立迴圈追蹤表(Trace Table)」,將程式結構依外層迴圈分為 5 次迭代,分別推導每列的空白數與星號數:
- 外層迴圈:
for (int i = 1; i <= 5; i++)
- 控制總列數,變數 依序取值為 ,共執行 5 列。
- 第一組內層迴圈(輸出空白):
for (int j = 1; j <= i; j++)
- 控制每列前置空白數。當外層為第 列時, 從 遞增至 ,故印出 個空白
' '。
- 第二組內層迴圈(輸出星號):
for (int j = 1; j <= 6 - i; j++)
- 控制星號輸出。迴圈條件為 ,每次迴圈印出
"**"(2 個星號)。 - 總星號數為: 個星號。
- 換行指令:
System.out.println
- 兩組內層迴圈執行完畢後換行,進入下一列。
逐列執行推導表
| 外層變數 | 空白迴圈次數 () | 印出空白數 | 星號迴圈次數 () | 印出星號數 ( 次數) | 該列輸出樣式 |
|---|---|---|---|---|---|
| (1 次) | 1 | (5 次) | 10 | 1 個空白 + 10 個星號 | |
| (2 次) | 2 | (4 次) | 8 | 2 個空白 + 8 個星號 |
第 二 題25 分
質數(prime number)是大於 1 的自然數中,只能被 1 和自身整除的數。例如,2、3、5、7、……。
試在不使用 Java 中質數相關 API 的情況下,撰寫 Java main() 程式(不要另訂 class、method 或 function),來找出小於 500 的所有質數,其結果列印必須如下:
2 is prime. 3 is prime. 5 is prime. 7 is prime. 11 is prime. 13 is prime. 17 is prime. 19 is prime. 23 is prime. . . . 491 is prime. 499 is prime.
95 primes found.
登入後即可作答並保存紀錄。
核心觀念
- 質數(Prime Number)定義: 質數是指大於 1 的正整數中,除了 1 和自身以外,無法被其他正整數整除的數。最小的質數為 2。
- 試除法(Trial Division)及其上界: 若正整數 為合數,則必可分解為兩個整數因數相乘,即 。若 與 皆大於 ,則 ,產生矛盾。因此合數 必存在至少一個不大於 的因數。檢驗 是否為質數時,僅需檢查 到 之間的所有整數是否能整除 即可,運算條件可表達成 ,時間複雜度由 降至 。
- 巢狀迴圈(Nested Loops)與流程控制:
- 外層迴圈:遍歷候選數值範圍( 至 )。
- 內層迴圈:對當前數值進行因數試除,搭配布林旗標(Boolean Flag)記錄是否為質數;一旦發現能被整除(餘數為 0),立即使用
break敘述中斷內層迴圈,以節省不必要的計算。
- 國考題意限制遵循:
題目明訂「不要另訂 class、method 或 function」,因此不得宣告額外的輔助類別(如自訂演算法類別)或自訂方法(如
static boolean isPrime(int n)),所有檢驗流程、計數與列印均須直接整合在main方法中。
解題方法
- 定義變數與計數器:
宣告整數變數
count作為累計質數個數的計數器,初值設為 0。 - 外層迴圈遍歷候選區間: 題目要求「小於 500 的所有質數」,因此外層迴圈變數 從最小質數 開始遞增,終止條件為 (即最大檢查至 499)。
- 內層迴圈進行質數判定:
- 每輪外層迴圈開始時,宣告布林旗標
boolean isPrime = true;。 - 內層迴圈以變數 作為除數,從 開始檢查,條件設為 。
- 若 (即
i % j == 0),代表 為合數,將isPrime設為false並執行break跳出內層迴圈。
- 輸出結果與累加計數:
第 三 題20 分
請以遞迴(recursive)的方式撰寫下列 Java 程式片斷中的 method sumOfEvens()。
sumOfEvens(n) 會回傳小於或等於 的所有正偶數的總和,例如 sumOfEvens(6) 會回傳 12,因為 。sumOfEvens() 完成後,必須確保 main() 執行後會印出正確結果,不需檢查 是否為含零的正整數。
public class Problem3 { public static int sumOfEvens(int x) { … }
public static void main(String[] args)
{
System.out.printf("sumOfEvens(0) = %d\n", sumOfEvens(0));
System.out.printf("sumOfEvens(1) = %d\n", sumOfEvens(1));
System.out.printf("sumOfEvens(2) = %d\n", sumOfEvens(2));
System.out.printf("sumOfEvens(10) = %d\n", sumOfEvens(10));
System.out.printf("sumOfEvens(15) = %d\n", sumOfEvens(15));
}
}
執行結果:
sumOfEvens(0) = 0 sumOfEvens(1) = 0 sumOfEvens(2) = 2 sumOfEvens(10) = 30 sumOfEvens(15) = 56
登入後即可作答並保存紀錄。
核心觀念
本題評量遞迴函式(Recursive Method)之設計與邏輯分支,涵蓋以下核心要點:
- 遞迴的兩大要素:
- 基準條件/終止條件(Base Case):遞迴停止呼叫自身並直接回傳結果的臨界狀態,用於避免程式陷入無窮遞迴導致堆疊溢位(
StackOverflowError)。 - 遞迴步驟(Recursive Step):將大問題分解為結構相同但規模較小的子問題,並藉由自我呼叫進行數值累加。
- 正偶數的定義與數論性質:
- 正偶數集合為 。
- 包含 與 的情況下,小於或等於其值的正偶數不存在,其總和定義為 。
- 奇偶數分流處理:
- 若 為偶數(),當前數值須計入總和,並遞迴尋求下一個偶數()的總和。
- 若 為奇數(),當前數值不屬於正偶數,不應計入總和,問題可直接等價轉化為求小於或等於 的正偶數總和。
解題方法
本題要求計算小於或等於 的所有正偶數總和。依據遞迴架構,解題步驟推導如下:
步驟一:確立終止條件(Base Case)
最小的正偶數為 。因此,當傳入的參數 時(例如題目測試資料中的 或 ),集合中沒有任何正偶數,應直接回傳 :
步驟二:處理奇數情況(Odd Case)
若 為奇數(即 x % 2 != 0),因為 本身不是偶數,不得累加至總和中。小於或等於奇數 的正偶數集合,與小於或等於 的正偶數集合完全相同,故直接回傳:
步驟三:處理偶數情況(Even Case)
若 為大於等於 的偶數(即 x % 2 == 0), 本身為有效正偶數,應將 加上前一個偶數()為上限的正偶數總和:
數學遞迴定義式
綜合上述分析,可建立完整的遞迴關係式:
選項分析
本題為程式實作題(申論題),無選項。以下針對題目給定的五組測試資料進行程式追蹤與驗證:
sumOfEvens(0):
- 滿足 條件,直接回傳 。
- 輸出:
sumOfEvens(0) = 0(正確)。
第 四 題15 分
請寫出以下 Python 程式的執行結果。
def secret(nums, target): seen = [] for index, num in enumerate(nums): other = target - num if other in seen: return [seen[other], index] else: seen[num] = index return []
print(secret([1, 3, 5], 4)) print(secret([2, 3, 6, 8, 10], 16)) print(secret([1, 3, 5], 7))
登入後即可作答並保存紀錄。
核心觀念
- Python 資料結構特性(串列 List 與 字典 Dictionary):
- 串列(
list):以連續整數為索引的有序序列。在 Python 中,不能直接對超過現有索引長度的位置進行指定賦值(如list[k] = v,當 時會拋出IndexError)。 - 字典(
dict):以雜湊表(Hash Table)實作的鍵值對(Key-Value Pair)映射結構。可動態以任意不可變物件作為鍵新增或查詢項目(如dict[k] = v)。
- 經典演算法「兩數之和」(Two Sum):
- 核心邏輯在於走訪數列時,對於當前數值 ,計算其互補數 。
- 利用暫存結構記錄「數值 出現索引」,達到平均時間複雜度 即可找出相加等於目標值之兩數索引。
- 內建函式與運算子:
enumerate(nums):每次迭代同時產生目前元素之「索引(index)」與「數值(num)」。in運算子:在串列中為線性搜尋(),在字典中則為檢查「鍵(Key)」是否存在(平均 )。
解題方法
本題在國考評分上存在「純語法嚴格執行」與「命題原意(修正筆誤)」兩種層次,標準作答須依序推導說明:
一、 嚴格依原題程式碼追蹤(語法與執行階段)
- 執行第一道呼叫
secret([1, 3, 5], 4):
- 函式第 2 行宣告
seen = [],建立一個長度為 的空串列。 - 進入
for迴圈第 1 輪:index = 0,num = 1。 - 計算互補數:。
- 判斷
if other in seen:3 in []為False。 - 進入
else:區塊,執行seen[num] = index,即seen[1] = 0。 - 程式中斷:由於
seen為長度 0 的空串列,索引 1 已超出串列邊界,Python 直譯器立即拋出IndexError: list assignment index out of range,導致程式崩潰中斷,後續所有語句均無法執行。
二、 命題原意推導(假設第 2 行更正為字典 seen = {})
出題委員原意係以 Python 字典實作經典 Two Sum 演算法,若將 seen = [] 視為出題筆誤並修正為 seen = {},各次呼叫推導如下:
- 第一組:
print(secret([1, 3, 5], 4))
- 初始:
seen = {} - 輪次 1(
index = 0,num = 1): - 。
- ,進入
else執行seen[1] = 0(目前seen = {1: 0})。 - 輪次 2(
index = 1,num = 3): - 。
- 成立,執行
return [seen[1], index]回傳[0, 1]。 - 輸出結果:
[0, 1]
- 第二組:
print(secret([2, 3, 6, 8, 10], 16))
- 初始:
seen = {} - 輪次 1(
index = 0,num = 2):,寫入seen[2] = 0。
第 五 題25 分
下列 Java 程式有三個類別(class):TeeShirt、CustomTee and DemoTees,其中 CustomTee 繼承 TeeShirt,而 DemoTees 為測試類別。試回答以下問題:
(一)請撰寫 TeeShirt 類別中的
public String toString()
格式請參考執行後結果。
(二)請撰寫 CustomTee 類別中的
public String toString()
格式請參考執行後結果。
(三)在 main() 中,以 array 的方式和兩個 for 迴圈,產生 5 件 T 恤,依序印出每件 T 恤屬性,最後加總 5 件的總價,結果顯示如下。
public class TeeShirt { private int orderNumber; private String size; private String color; private double price;
public void setOrderNumber(int num)
{
orderNumber = num;
}
public void setSize(String sz)
{
size = sz;
if (size == "XXL" || size == "XXXL")
price = 22.99;
else
price = 19.99;
}
public void setColor(String color)
{
this.color = color;
}
public int getOrderNumber()
{
return orderNumber;
}
public String getSize()
{
return size;
}
public String getColor()
{
return color;
}
public double getPrice()
{
return price;
}
public String toString()
{
…
}
}
public class CustomTee extends TeeShirt { private String slogan;
public void setSlogan(String slgn)
{
slogan = slgn;
}
public String getSlogan()
{
return slogan;
}
public String toString()
{
…
}
}
public class DemoTees { public static void main(String[] args) { … } }
執行結果:
Order # 100 Description: S red Slogan: Cute Girl Price: $19.99
Order # 101 Description: S red Slogan: Cute Girl Price: $19.99
Order # 102 Description: XXL blue Slogan: Happy Boy Price: $22.99
Order # 103 Description: XXL blue Slogan: Happy Boy Price: $22.99
Order # 104 Description: XXL blue Slogan: Happy Boy Price: $22.99
Total: $108.95
登入後即可作答並保存紀錄。
核心觀念
本題為標準的 Java 物件導向程式設計(OOP)實作題,評量考生對基礎語法與物件導向核心特性的掌握程度,主要涵蓋以下重點:
- 繼承(Inheritance)與方法覆寫(Method Overriding):子類別
CustomTee繼承父類別TeeShirt,並覆寫繼承自java.lang.Object的public String toString方法,提供自訂的字串表現形式。 - 封裝(Encapsulation)與存取權限(Access Modifiers):父類別宣告為
private的欄位(如orderNumber、size、color、price),子類別無法直接存取,必須透過父類別所宣告的public取值方法(Getter Methods)間接取得。 - 物件陣列(Array of Objects)之建立與操作:
- 物件陣列宣告僅配置參考指標空間,陣列元素預設為
null,必須透過new逐一實例化各個元素。 - 透過迴圈巡訪(Traversal)批次初始化屬性、呼叫方法與累加數值。
- 業務邏輯連動:觀察
TeeShirt類別可發現,該類別並無setPrice方法,價格係於呼叫setSize時由內部邏輯自動指派。
解題方法
(一)TeeShirt 類別之 toString
對照題目提供的「執行結果」,若單純印出父類別 TeeShirt,其屬性包含訂單編號(orderNumber)、尺寸(size)、顏色(color)與價格(price)。
- 第一行輸出訂單編號:
Order # 100。 - 第二行縮排 4 格空白(或定位字元
\t),輸出描述:Description: S red。 - 第三行縮排 4 格空白,輸出價格:
Price: $19.99。 - 因程式碼身處
TeeShirt類別內部,可直接存取自身的私有成員變數。
(二)CustomTee 類別之 toString
子類別 CustomTee 增加了自訂標語屬性 slogan。
- 觀察執行結果,標語插入於
Description與Price之間:Slogan: Cute Girl。 - 關鍵切入點:
CustomTee為子類別,而父類別TeeShirt的屬性皆為private,在子類別中直接存取orderNumber等變數將導致編譯錯誤;因此必須呼叫getOrderNumber、getSize、getColor、getPrice取得父類別屬性值,而自身欄位slogan則可直接存取。
(三)DemoTees 類別之 main 實作
題目要求「以 array 的方式和兩個 for 迴圈,產生 5 件 T 恤,依序印出每件 T 恤屬性,最後加總 5 件的總價」:
- 陣列配置:宣告長度為 5 的
CustomTee陣列:CustomTee[] tees = new CustomTee[5]; - 第一個 for 迴圈(產生與初始化):
- 巡訪索引 至 。
- 實例化各元素:
tees[i] = new CustomTee;。 - 依序設定訂單編號:
tees[i].setOrderNumber(100 + i);。 - 觀察執行結果可知:
- 前 2 件():尺寸為
"S"、顏色為"red"、標語為"Cute Girl"(呼叫setSize("S")自動設定價格為 $19.99)。 - 後 3 件():尺寸為
"XXL"、顏色為"blue"、標語為"Happy Boy"(呼叫setSize("XXL")自動設定價格為