108 高普考普通考試 資訊處理 程式設計概要 考古題詳解

108 年・高普考・普通考試・資訊處理
試題代碼 程式設計概要

第 一 題25 分

Java 程式 PreStars 會印出什麼結果?維持巢狀 for 迴圈架構,小修 PreStars,讓它印出以下的星星構圖。

public class PreStars { public static void main(String[] args) { for (int i=1; i<=5; i++) { for (int j=1; j<=i; j++) System.out.print('*'); System.out.println(); } } }

應印出:





******
 *****
  ****
   ***
    **
     *

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

這一題的完整詳解

核心觀念

本題評量巢狀迴圈(Nested Loops)的執行流程控制與圖形輸出規律建模能力,為國考資訊處理類科《程式設計概要》的經典基本題型。核心觀念包含:

  1. 巢狀迴圈的控制分工:
  • 外層迴圈(Outer Loop):負責控制輸出的「列數(Rows)」與換行時機。
  • 內層迴圈(Inner Loop):負責控制該列中各「行(Columns)」所輸出的字元內容與次數。
  1. 輸出函數的差異:
  • System.out.print:輸出字元後不換行,用於在同一列連續輸出空白或星號。
  • System.out.println:輸出換行字元(移至下一列開頭)。
  1. 線性關係規律推導:
  • 圖形輸出題必須將幾何構圖轉換為代數關係式。設外層列指標為 ii,推導出該列所需「空白字元數」與「星號字元數」關於 ii 的一次方程式(等差數列)。

解題方法

第一部分:分析原程式 PreStars 的輸出結果

原程式結構如下:

for (int i=1; i<=5; i++) {
 for (int j=1; j<=i; j++)
 System.out.print('*');
 System.out.println;
}

追蹤外層與內層迴圈變數的迭代過程:

  • 外層迴圈 ii 從 11 遞增至 55,共執行 55 次,代表輸出 55 列。
  • 當 i=1i = 1:內層 jj 範圍為 1≤j≤11 \le j \le 1,執行 11 次,印出 *,接著換行。
  • 當 i=2i = 2:內層 jj 範圍為 1≤j≤21 \le j \le 2,執行 22 次,印出 **,接著換行。
  • 當 i=3i = 3:內層 jj 範圍為 1≤j≤31 \le j \le 3,執行 33 次,印出 ***,接著換行。
  • 當 i=4i = 4:內層 jj 範圍為 1≤j≤41 \le j \le 4,執行 44 次,印出 ****,接著換行。
  • 當 i=5i = 5:內層 jj 範圍為 1≤j≤51 \le j \le 5,執行 55 次,印出 *****,接著換行。

因此,原程式會輸出一個高度為 55 列、靠左對齊的直角三角形星號圖形。


第二部分:修改程式以輸出目標星號構圖

步驟一:分析目標圖形的數學規律

題目要求的構圖共有 1010 列,每列由前導空白(Space)與星號(*)組成。 以列指標 ii(令 ii 從 11 到 1010)建立對應關係表:

列號 ii前導空白數星號數規律推導
11001010空白 =i−1= i - 1;星號 =11−i= 11 - i
221199空白 =i−1= i - 1;星號 =11−i= 11 - i
332288空白 =i−1= i - 1;星號 =11−i= 11 - i
⋮\vdots⋮\vdots⋮\vdots⋮\vdots
10109911空白 =i−1= i - 1;星號 =11−i= 11 - i

通式驗算:

  • 前導空白數為公差為 +1+1 的等差數列:首項為 00,故第 ii 列的空白數為 i−1i - 1。
  • 星號數為公差為 −1-1 的等差數列:首項為 1010,故第 ii 列的星號數為 10−(i−1)=11−i10 - (i - 1) = 11 - i。
步驟二:程式修改架構設計

維持題目要求的「巢狀 for 迴圈架構」與「小修」原則,評分實務上採納以下兩種標準作法:

  • 解法 A(經典雙內層迴圈法): 外層迴圈維持 ii 控制列數(範圍改為 11 到 1010)。
🔒

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

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

免費註冊

第 二 題25 分

下列為 Reverse class 的程式規範與其執行結果,試以遞迴(recursive)的方式完成副程式 reverse(int[] arr, int x)。撰寫時,必須使用相同的參數名稱與資料型態。

reverse(int[] arr, int x) 會回傳一個倒過來擺置的整數串:arr[n-1]、arr[n-2]、……、arr[x+1]、arr[x],假設 arr 內共有 nn 個元素,而且 x≤nx\le n。

public class Reverse { public static String reverse(int[] arr, int x) {

}

public static void main(String[] args)
{
    int[] intArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    String results = reverse(intArr, 2);
    System.out.println(results);
    System.out.println(reverse(intArr, 7));
}

}

執行結果:

10 9 8 7 6 5 4 3 10 9 8

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

這一題的完整詳解

核心觀念

本題評量遞迴副程式(Recursive Subroutine)​的設計能力與字串處理技巧,重點概念包含:

  1. 遞迴三要素:
  • 基底條件(Base Case / 終止條件):停止遞迴並直接回傳結果的邊界,避免無窮遞迴導致堆疊溢位(StackOverflowError)。
  • 遞迴步驟(Recursive Step):將原問題拆解為結構相同但規模較小的子問題。
  • 向終止條件逼近:每次遞迴呼叫時,傳入的狀態必須往基底條件推進。
  1. 呼叫堆疊(Call Stack)與回溯特性(Backtracking): 題目要求輸出反向整數串(從索引 n−1n-1 倒數輸出至 xx)。在副程式參數固定為 (int[] arr, int x) 且不可增減參數的限制下,必須利用呼叫堆疊的「後進先出(LIFO)」特性:先遞迴深入至陣列尾端(xx 逐次加 1 逼近 n−1n-1),於回溯階段(Return)才將當前元素 arr[x]arr[x] 串接在後方。

解題方法

1. 題意與子問題分析

給定陣列長度為 nn(即 arr.length),需回傳的整數串為: arr[n−1],arr[n−2],…,arr[x+1],arr[x]arr[n-1], arr[n-2], \dots, arr[x+1], arr[x]

觀察子問題的關係:

  • 若已取得 reverse(arr, x + 1) 的結果:arr[n−1]…arr[x+1]arr[n-1] \dots arr[x+1]。
  • 則 reverse(arr, x) 的完整字串即為:reverse(arr, x + 1) + " " + arr[x]。

2. 基底條件(Base Case)設計

  • 極限邊界:題目指出 x≤nx \le n。若 x=nx = n(即 x≥arr.lengthx \ge arr.length),表示不包含任何元素,應回傳空字串 ""。
  • 最後一個元素:當 x=n−1x = n - 1(即 arr.length - 1)時,為倒序字串的第一個輸出元素(即 arr[n−1]arr[n-1])。此時直接將該整數轉為字串回傳,不需前置空格,作為遞迴終止的基準點。

3. 追蹤驗算(Trace)

以 reverse(intArr, 7) 為例(其中 intArr 長度 n=10n=10):

  1. 呼叫 reverse(arr, 7):等待 reverse(arr, 8) 的結果。
  2. 呼叫 reverse(arr, 8):等待 reverse(arr, 9) 的結果。
  3. 呼叫 reverse(arr, 9):符合 x=9=n−1x = 9 = n-1,直接回傳字串 "10"。
  4. 回溯至第 2 步:回傳 "10" + " " + arr[8] →\rightarrow "10 9"。
  5. 回溯至第 1 步:回傳 "10 9" + " " + arr[7] →\rightarrow "10 9 8"。

輸出結果與題目範例完全吻合,且開頭與尾端均無多餘空格。


選項分析

🔒

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

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

免費註冊

第 三 題15 分

下列 Python 程式的執行結果為何?

list = [2,2,3,7,7,7,9,9,10,10] count = 1 current = list[0]

for i in list: if i > current: list[count] = i count += 1 current = i

last = len(list)

if last > count: for i in range(count, last): list.pop()

print("count = ", count) print("list = ", list)

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

這一題的完整詳解

核心觀念

本題為經典的已排序串列原地去重複演算法(In-place Remove Duplicates from Sorted Array),核心測驗考生對以下四項觀念的理解:

  1. 雙指標(快慢指標)機制:利用快指標(for 迴圈中的 ii)循序走訪串列,慢指標(變數 count)記錄不重複元素的個數,同時標記下一個新相異元素應覆寫的索引位置。
  2. 條件覆寫(In-place Modification):若快指標數值大於當前記錄的最大相異值(i>currenti > current),則將該值寫入慢指標位置 list[count],並推進慢指標(count←count+1count \leftarrow count + 1)。
  3. 區間迭代與尾端刪除:range(count, last) 產生半開區間 [count,last)[count, last) 的整數序列,透過 list.pop 逐次自串列末端移除元素,將多餘的舊元素截除。
  4. Python print 函式之預設引數:print 傳入多個引數時,預設會以單一空白字元(sep=' ')作為引數間的分隔符號。

解題方法

解題切入點採用程式分段追蹤法,將程式碼拆解為三個主要階段進行推導:

階段一:變數初始化

  • 初始串列:list = [2, 2, 3, 7, 7, 7, 9, 9, 10, 10],長度為 10。
  • count = 1:代表已保留第 0 個元素,去重複後的有效長度從 1 開始計數。
  • current = list[0] = 2:記錄目前最新的相異值基準。

階段二:for 迴圈走訪與覆寫

迴圈依序取出 list 中的元素 ii,當 i>currenti > current 時觸發覆寫與累加:

迭代次數元素 ii判斷式 i>currenti > current執行動作countcurrentlist 當前內容
122>22 > 2(False)不執行12[2, 2, 3, 7, 7, 7, 9, 9, 10, 10]
222>22 > 2(False)不執行12[2, 2, 3, 7, 7, 7, 9, 9, 10, 10]
333>23 > 2(True)list[1] = 323[2, 3, 3, 7, 7, 7, 9, 9, 10, 10]
477>37 > 3(True)list[2] = 737[2, 3, 7, 7, 7, 7, 9, 9, 10, 10]
577>77 > 7(False)不執行37[2, 3, 7, 7, 7, 7, 9, 9, 10, 10]
677>77 > 7(False)不執行37[2, 3, 7, 7, 7, 7, 9, 9, 10, 10]
799>79 > 7(True)list[3] = 949[2, 3, 7, 9, 7, 7, 9, 9, 10, 10]
899>99 > 9(False)不執行49[2, 3, 7, 9, 7, 7, 9, 9, 10, 10]
91010>910 > 9(True)list[4] = 10510[2, 3, 7, 9, 10, 7, 9, 9, 10, 10]
🔒

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

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

免費註冊

第 四 題35 分

數學中複數是實數的延伸,複數通常表示為 a+bia+bi 或 (a,b)(a,b),其中 a,ba,b 為實數,分別稱為複數的實部與虛部,ii 為虛數單位,且 i2=−1i^2=-1。複數的加、減、乘、除運算定義如下:

(a+bi)+(c+di)=(a+c)+(b+d)i(a+bi)+(c+di)=(a+c)+(b+d)i

(a+bi)−(c+di)=(a−c)+(b−d)i(a+bi)-(c+di)=(a-c)+(b-d)i

(a+bi)∗(c+di)=(ac−bd)+(ad+bc)i(a+bi)*(c+di)=(ac-bd)+(ad+bc)i

(a+bi)/(c+di)=((ac+bd)/(c2+d2))+((bc−ad)/(c2+d2))i(a+bi)/(c+di)=((ac+bd)/(c^2+d^2))+((bc-ad)/(c^2+d^2))i

試參考以下程式回答問題:

public class Complex { private double real; private double imaginary;

public Complex()
{
    this(0.0, 0.0);
}

public Complex(double r, double i)
{
    real = r;
    imaginary = i;
}

public Complex add(Complex right)
{
    return new Complex(real + right.real,
                       imaginary + right.imaginary);
}

public Complex subtract(Complex right)
{
    return new Complex(real - right.real,
                       imaginary - right.imaginary);
}

public String toString()
{
    return String.format("(%.1f, %.1f)", real, imaginary);
}

} // end class Complex

public class ComplexTest { public static void main(String[] args) { Complex x = new Complex(1, 1); Complex y = new Complex(2, 2);

    System.out.printf("x = %s%n", x.toString());
    System.out.printf("y = %s%n", y);
}

} // end class ComplexTest

(一)此程式的列印結果為何?

(二)利用 add(),在 ComplexTest.java 中加入一行程式,以印出「x + y = (3.0, 3.0)」。

(三)於 Complex.java 中撰寫:

public Complex division(Complex right)

回傳資料型態與參數命名必須分別為 Complex 與 right。

(四)利用 division(),在 ComplexTest.java 中算出 y=(2,2)y=(2,2) 的倒數(如果 y′∗y=1y'*y=1,則稱 y′y' 為 yy 的倒數),並列印出有意義的訊息。

(五)撰寫 public String standardForm(),以印出複數的另一表示法 a+bia+bi。注意:

0.0+bi0.0+bi 要表示為 bibi;

a+0.0ia+0.0i 要表示為 aa;

a+1.0ia+1.0i 要表示為 a+ia+i。

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

這一題的完整詳解

核心觀念

本題為典型的「物件導向程式設計(OOP)」實作題,重點測驗 Java 類別的封裝、物件狀態操作與數學模型對應能力:

  1. 物件封裝與成員存取權限:類別內部的 private 成員變數(real 與 imaginary),在同一個類別的不同物件實例(Instance)之間具備存取權限。例如在 add(Complex right) 或 division(Complex right) 中,可直接存取 right.real。
  2. toString 覆寫與輸出機制:Java 中任何物件傳入 System.out.printf("%s") 或 System.out.print 時,皆會自動呼叫該物件的 toString 方法。
  3. 複數除法與倒數的代數定義:
  • 複數除法: (a+bi)/(c+di)=ac+bdc2+d2+bc−adc2+d2i(a+bi)/(c+di) = \frac{ac+bd}{c^2+d^2} + \frac{bc-ad}{c^2+d^2}i
  • 倒數定義:若 y′∗y=1y' * y = 1,則 y′=1/y=(1.0+0.0i)/yy' = 1 / y = (1.0 + 0.0i) / y。
  1. 字串格式化與邊界條件判斷:輸出特殊代數格式時,需根據實部與虛部的數值狀態(0.00.0、1.01.0、正負號)進行條件分支處理。

解題方法與逐步推導

(一)列印結果分析

  1. 程式建立兩個複數物件:
  • x 的實部為 1.0、虛部為 1.0。
  • y 的實部為 2.0、虛部為 2.0。
  1. Complex 類別覆寫了 toString,其格式化字串為 String.format("(%.1f, %.1f)", real, imaginary),保留小數點後一位。
  2. 第一行輸出:System.out.printf("x = %s%n", x.toString);
  • 明確呼叫 x.toString,回傳 "(1.0, 1.0)"。
  • 印出:x = (1.0, 1.0) 並換行。
  1. 第二行輸出:System.out.printf("y = %s%n", y);
  • %s 轉換符會自動呼叫 y.toString,回傳 "(2.0, 2.0)"。
  • 印出:y = (2.0, 2.0) 並換行。

(二)利用 add 列印相加結果

  1. x.add(y) 會以 x 為主體,將 y 作為引數傳入,計算 (1+2)+(1+2)i(1+2) + (1+2)i,回傳一個新的 Complex(3.0, 3.0) 物件。
  2. 題目要求印出 x + y = (3.0, 3.0),配合 ComplexTest.java 原有的 printf 風格,直接將 x.add(y) 置入輸出敘述中:
System.out.printf("x + y = %s%n", x.add(y));

(亦可使用 System.out.println("x + y = " + x.add(y));)

(三)撰寫 division(Complex right)

  1. 方法簽章:依題意必須為 public Complex division(Complex right)。
  2. 數學公式與程式變數對應:
  • 被除數(this):a=reala = \text{real},b=imaginaryb = \text{imaginary}。
  • 除數(right):c=right.realc = \text{right.real},d=right.imaginaryd = \text{right.imaginary}。
  • 分母:denominator=c2+d2=right.real×right.real+right.imaginary×right.imaginary\text{denominator} = c^2 + d^2 = \text{right.real} \times \text{right.real} + \text{right.imaginary} \times \text{right.imaginary}。
  • 新實部:ac+bdc2+d2=real×right.real+imaginary×right.imaginarydenominator\frac{ac+bd}{c^2+d^2} = \frac{\text{real} \times \text{right.real} + \text{imaginary} \times \text{right.imaginary}}{\text{denominator}}。
  • 新虛部:bc−adc2+d2=imaginary×right.real−real×right.imaginarydenominator\frac{bc-ad}{c^2+d^2} = \frac{\text{imaginary} \times \text{right.real} - \text{real} \times \text{right.imaginary}}{\text{denominator}}。
  1. 回傳值:透過建構子回傳包含計算後之實部與虛部的新 Complex 物件。

(四)利用 division 計算 yy 的倒數

  1. 倒數之代數轉換:
  • 實數 11 的複數表示為 1+0i1 + 0i,即 new Complex(1.0, 0.0)。
  • yy 的倒數 y′=1/yy' = 1 / y,即以複數 11 呼叫 division(y)。
  1. 程式實作:
  • 宣告代表 11 的複數物件,或直接鏈式呼叫:new Complex(1.0, 0.0).division(y)。
  • 將結果輸出為有意義之說明文字(包含計算結果)。
  • 代數驗算: y=2+2i  ⟹  y′=12+2i=2−2i22+22=2−2i8=0.25−0.25iy = 2 + 2i \implies y' = \frac{1}{2+2i} = \frac{2 - 2i}{2^2 + 2^2} = \frac{2 - 2i}{8} = 0.25 - 0.25i 經 toString 的 %.1f 格式化後輸出為 (0.3, -0.3)。
🔒

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

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

免費註冊

其他考古題