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

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

第 一 題24 分

請完成以下 Java 程式(class Circle:code 1~code 3,class Rectangle:code 4~code 6,main:code 7~code 8),使其可以印出最後一張圖的內容。

  • 第一、三個方框:code 1、code 4,class Circle/Rectangle 宣告繼承父類別。
  • 第二個方框:code 2、code 3,實作 Circle 計算面積、周長的方法。
  • 第四個方框:code 5、code 6,實作 Rectangle 計算面積、周長的方法。
  • 第五個方框:code 7、code 8,多型方式宣告 Circle/Rectangle 物件。

程式碼如下:

package PDconcept_OO;

import java.util.ArrayList;

//===== Interface:定義所有幾何形狀都必須實作的方法 =====// interface IShape { double computeArea(); double computePerimeter(); }

//===== 父類別 Shape,負責統一對外呼叫、顯示結果 =====// abstract class Shape implements IShape { protected String shapeName;

public Shape(String shapeName) {
    this.shapeName = shapeName;
}

public abstract double computeArea();

public abstract double computePerimeter();

public void showResult() {
    System.out.println("Shape: " + shapeName);
    System.out.printf("Area: %.2f%n", computeArea());
    System.out.printf("Perimeter: %.2f%n", computePerimeter());
    System.out.println("--------------------");
}

}

//===== Circle 類別:繼承 Shape,實作圓形計算 =====// class Circle ____ { private double radius;

public Circle(double radius) {
    super("Circle");
    this.radius = radius;
}

____  // code 2:實作計算面積
____  // code 3:實作計算周長

}

//===== Rectangle 類別:繼承 Shape,實作矩形計算 =====// class Rectangle ____ { private double width; private double height;

public Rectangle(double width, double height) {
    super("Rectangle");
    this.width = width;
    this.height = height;
}

____  // code 5:實作計算面積
____  // code 6:實作計算周長

}

//===== 主程式呼叫範例 =====// public class OO { public static void main(String[] args) { Shape s1 = new Circle(5); Shape s2 = new Rectangle(4, 6);

    s1.showResult();
    s2.showResult();

    ArrayList<Shape> shapes = new ArrayList<>();
    shapes.add(____);  // code 7:宣告物件
    shapes.add(____);  // code 8:宣告物件

    for (Shape shape : shapes) {
        shape.showResult();
    }
}

}

程式輸出如下:

Shape: Circle Area: 78.54 Perimeter: 31.42

Shape: Rectangle Area: 24.00 Perimeter: 20.00

Shape: Circle Area: 314.16 Perimeter: 62.83

Shape: Rectangle Area: 29.25 Perimeter: 22.00

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

這一題的完整詳解

核心觀念

本題考查 Java 的繼承、抽象類別、多型與方法覆寫,以及圓形、矩形的面積和周長公式。

  • IShape 是介面,定義所有形狀都必須提供的 computeArea 與 computePerimeter。
  • 抽象類別 Shape 實作 IShape,並將這兩個方法宣告為抽象方法。子類別必須提供方法實作。
  • Circle 與 Rectangle 繼承 Shape,以 @Override 覆寫計算方法。
  • Shape 型別的參考可以指向 Circle 或 Rectangle 物件。呼叫覆寫方法時,Java 會依物件的實際型別執行對應方法,這就是多型。

計算公式為:

圓面積=πr2,圓周長=2πr\text{圓面積}=\pi r^2,\qquad \text{圓周長}=2\pi r 矩形面積=寬×高,矩形周長=2(寬+高)\text{矩形面積}=寬\times高,\qquad \text{矩形周長}=2(寬+高)

解題方法

先依類別關係填入繼承宣告:Circle 與 Rectangle 都繼承 Shape,因此使用 extends Shape。

接著,依各類別的欄位撰寫計算方法:

  • Circle 使用 radius 計算面積與周長。
  • Rectangle 使用 width、height 計算面積與周長。
  • 方法回傳型別為 double,與父類別宣告及介面規格一致。

最後,ArrayList<Shape> 的元素型別是 Shape,因此可加入以 Shape 型別宣告、實際建立為圓形或矩形的物件。以下以半徑 10 的圓,以及寬 3.5、高 4.5 的矩形,使輸出符合題目。

填入程式碼

class Circle extends Shape {
 private double radius;

 public Circle(double radius) {
 super("Circle");
 this.radius = radius;
 }

 @Override
 public double computeArea {
 return Math.PI * radius * radius;
 }

 @Override
 public double computePerimeter {
 return 2 * Math.PI * radius;
 }
}

class Rectangle extends Shape {
 private double width;
 private double height;

 public Rectangle(double width, double height) {
 super("Rectangle");
 this.width = width;
 this.height = height;
 }

 @Override
 public double computeArea {
 return width * height;
 }

 @Override
 public double computePerimeter {
 return 2 * (width + height);
 }
}

main 中的兩個空格填入:

🔒

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

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

免費註冊

第 二 題20 分

請說明如下 C# 程式,正確執行時的輸出結果為何?如若無法正確執行(即會出現執行時期的錯誤),請說明應如何修正才能正常執行及輸出結果為何。

public class ReferenceDT { public static void refDT(int[] rdt) { rdt[0] = 10; rdt = new int[] { 100, 200, 300 }; rdt[1] = 20; }

public static void refDT(ref int[] rdt)
{
    rdt[0] = 10;
    rdt = new int[] { 100, 200, 300 };
    rdt[1] = 20;
}

public static void printArray<E>(E[] source)
{
    if (source == null) {
        Console.WriteLine("null");
        return;
    }

    for (int i = 0; i < source.Length; i++) {
        Console.Write(source[i] + " ");
    }

    Console.WriteLine();
}

}

// 主程式中,執行的 code int[] data = { -10, -20, -30 };

Console.Write("Source --> "); ReferenceDT.printArray(data);

ReferenceDT.refDT(data); Console.Write("After refDT(data) --> "); ReferenceDT.printArray(data);

ReferenceDT.refDT(ref data); Console.Write("After refDT(ref data) --> "); ReferenceDT.printArray(data);

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

這一題的完整詳解

核心觀念

本題考查 C# 陣列是參考型別,以及一般參數傳遞與 ref 參數傳遞的差異。

  • 呼叫 refDT(int[] rdt) 時,方法取得的是陣列參考的副本。方法可透過此參考修改原陣列內容,但將 rdt 指向另一個新陣列,只會改變方法內的區域參考,不會改變呼叫端的 data。
  • 呼叫 refDT(ref int[] rdt) 時,ref 讓方法直接操作呼叫端的變數。方法將 rdt 指向新陣列後,呼叫端的 data 也會指向該新陣列。
  • 兩個方法名稱相同,但參數是否含 ref 不同,因此是不同的多載。呼叫時必須配合參數宣告使用 ref 關鍵字。

解題方法

依序追蹤呼叫端的 data 指向哪個陣列,以及各陣列元素如何變化。

  1. 初始時,data 指向陣列 {-10, -20, -30},因此第一次印出:
Source --> -10 -20 -30
  1. 呼叫 refDT(data),執行的是未使用 ref 的版本。
  • rdt[0] = 10; 透過參考副本修改原陣列,故原陣列變成 {10, -20, -30}。
  • rdt = new int[] { 100, 200, 300 }; 只讓方法內的 rdt 指向新陣列,呼叫端的 data 仍指向原陣列。
  • rdt[1] = 20; 修改新陣列,但方法結束後該陣列不再由 data 參照。

因此第二次印出:

After refDT(data) --> 10 -20 -30
🔒

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

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

免費註冊

第 三 題20 分

請說明如下 C 程式,正確執行時的輸出結果為何?如若無法正確執行(即會出現執行時期的錯誤),請說明應如何修正才能正常執行及輸出結果為何。

int* find2(int source[], int len, bool flag, int* newLen) { int first; int second; int startInd = 2; static int result[2];

if (source == NULL || len < 2) {
    *newLen = 0;
    return NULL;
}

if (flag)
{
    if (source[0] <= source[1]) {
        first = source[0];
        second = source[1];
    }
    else {
        first = source[1];
        second = source[0];
    }

    for (int i = startInd; i < len; i++)
    {
        if (source[i] > first) {
            second = first;
            first = source[i];
        }
        else if (source[i] < second) {
            second = source[i];
        }
    }

    printf("StartInd: %d, first: %d, second: %d\n",
           startInd, first, second);
}
else
{
    if (source[0] >= source[1]) {
        first = source[0];
        second = source[1];
    }
    else {
        first = source[1];
        second = source[0];
    }

    while (startInd < len)
    {
        if (source[startInd] > first) {
            second = first;
            first = source[startInd];
        }
        else if (source[startInd] > second) {
            second = source[startInd];
        }

        startInd++;
    }

    printf("StartInd: %d, first: %d, second: %d\n",
           startInd, first, second);
}

result[0] = first;
result[1] = second;
*newLen = 2;

return result;

}

// End of find2

void main() { int source[] = { 35, 12, 23, 11, 24, 36, 59, 48, 47 }; int len = sizeof(source) / sizeof(source[0]); int* data = source;

data = find2(data, len, true, &len);
printf("Result 1: %d, Result 2: %d\n", data[0], data[1]);

data = find2(data, len, false, &len);
printf("Result 1: %d, Result 2: %d\n", data[0], data[1]);

}

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

這一題的完整詳解

核心觀念

本題考查陣列走訪、指標與回傳值、static 區域陣列,以及函式參數經指標修改呼叫端變數的效果。

find2 依 flag 分別尋找兩個數值:

  • flag == true:尋找最大值與第二大值;程式以 < 更新 second,所以相同最大值不會被視為第二大值。
  • flag == false:尋找最大值與次大值;程式以 > 更新 second,相同最大值可以成為第二個值。
  • 結果存放在 static int result[2],函式回傳的指標指向這個陣列,因此函式返回後資料仍有效。
  • *newLen = 2 會改寫呼叫端傳入的整數。主程式把 len 同時當作來源陣列長度及 newLen,因此第一次呼叫後,len 會從 9 變成 2。

解題方法

先逐次追蹤呼叫中的 len,再依照每個分支的比較條件更新 first、second。

第一次呼叫:find2(data, len, true, &len)

呼叫時 len = 9,startInd = 2。前兩個元素為 35、12,因此初始化為 first = 35、second = 12。接著由索引 2 掃描至索引 8:

索引值更新後的 first、second
22335、23
31135、23
42435、24
53636、35
65959、36
74859、48
84759、48

迴圈結束時 startInd 仍是 2,因為 for 迴圈的索引變數是 i,不會改變 startInd。函式印出:

StartInd: 2, first: 59, second: 48

之後函式設定 *newLen = 2,也就是把主程式的 len 改成 2,並回傳 result。主程式接著印出:

Result 1: 59, Result 2: 48

第二次呼叫:find2(data, len, false, &len)

此時 data 指向第一次呼叫回傳的 result,內容為 {59, 48};而 len 已經是 2。因此第二次呼叫檢查的是這兩個結果,不是原始的九元素陣列。

因為 59 >= 48,初始化為 first = 59、second = 48。

🔒

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

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

免費註冊

第 四 題18 分

請說明如下 Python 程式,使用 PQ_recursive(3) 呼叫後,正確執行時的輸出結果為何?如若無法正確執行(即會出現執行時期的錯誤),請說明應如何修正才能正常執行及輸出結果為何。

def PQ_recursive(n, c1='Z', c2='Y', c3='X'): if n <= 0 or n > 9: return

PQ_recursive(n - 1, c1, c3, c2)
print(f"Move {n}: {c1} -> {c3}")
PQ_recursive(n - 1, c2, c1, c3)

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

這一題的完整詳解

核心觀念

本題考查 Python 函式的遞迴呼叫、預設參數,以及參數傳遞順序。程式意圖以遞迴方式列出移動步驟;每次呼叫都將三個位置參數 c1、c2、c3 傳入下一層。

解題方法

呼叫 PQ_recursive(3) 時,初始參數為 c1='Z'、c2='Y'、c3='X'。但遞迴呼叫會在尚未輸出任何文字時,先一路進入:

PQ_recursive(n - 1, c1, c3, c2)

各層的參數如下:

nc1c2c3
3ZYX
2ZXY
1ZYX
0ZXY

當 n=0 時,符合 n <= 0,函式直接 return。之後程式開始回到上一層執行,但該層接著呼叫:

PQ_recursive(n - 1, c2, c1, c3)

在 n=1 這層,傳入的參數為 n=0, c1='Y', c2='Z', c3='X'。這組值也會觸發基底條件並返回。此時 n=1 層執行 print,再回到 n=2 層。

🔒

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

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

免費註冊

第 五 題18 分

請完成如下的 JavaScript function 觸動方式(第一條粗黑線)及內容(第二~第六條粗黑線),可以顯示如下網頁頁面,並在按下「Submit」按鈕後,觸動 JS function 根據使用者的輸入,顯示計算複利的本利和。

🖼️【此處有附圖,請對照原卷】

HTML 程式碼如下:

<body> <h2>複利計算程式</h2>
<form onsubmit="____">
    <div>
        <label for="principal">本金:</label>
        <input type="number"
               id="principal"
               min="1000"
               max="100000"
               step="1000"
               value="10000"
               required>
    </div>

    <div>
        <label for="year">年數:</label>
        <input type="number"
               id="year"
               min="1"
               max="20"
               step="1"
               value="1"
               required>
    </div>

    <div>
        <label for="rate">年利率(%):</label>
        <input type="number"
               id="rate"
               min="0.01"
               max="100"
               step="0.01"
               value="2.0"
               required>
    </div>

    <div>
        <label for="amount">本利和:</label>
        <input type="text" id="amount" readonly>
    </div>

    <button type="submit">Submit</button>
</form>

<script>
    function calculateCompoundInterest(event) {
        event.preventDefault();

        let principal = ____;
        let year = ____;
        let rate = ____;
        let amount = ____;
        ____ = amount.toFixed(2);
    }
</script>
</body>

其中需填入:

  • 第一條粗黑線:onsubmit="____"
  • 第二條粗黑線:let principal = ____;
  • 第三條粗黑線:let year = ____;
  • 第四條粗黑線:let rate = ____;
  • 第五條粗黑線:let amount = ____;
  • 第六條粗黑線:____ = amount.toFixed(2);
🖼️ 本題原卷含圖表。基於試題來源之版權考量,本站不轉載原卷影像; 題目文字已完整轉錄,圖表請自行參閱考選部公告之試題原檔。

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

這一題的完整詳解

核心觀念

本題考查:

  • HTML 表單 onsubmit 事件的觸發方式。
  • 透過 document.getElementById(...).value 取得輸入值。
  • JavaScript 字串轉數值。
  • 複利公式:

A=P(1+r)nA=P(1+r)^n

其中:

  • PP:本金
  • rr:年利率的小數值
  • nn:年數
  • AA:本利和

題目中的利率輸入單位是百分比,例如 2.0 代表 2%2\%,因此計算時須除以 100100。

解題方法

第一條粗黑線位於 <form onsubmit="...">,按下 Submit 後會觸發表單提交事件,因此填入:

calculateCompoundInterest(event)

函式內先使用 event.preventDefault,避免表單送出後重新載入頁面。

本金、年數、年利率均由輸入欄位取得。由於 .value 取得的是字串,須使用 parseFloat 轉成數值:

let principal = parseFloat(document.getElementById("principal").value);
let year = parseFloat(document.getElementById("year").value);
let rate = parseFloat(document.getElementById("rate").value) / 100;

複利計算使用:

let amount = principal * Math.pow(1 + rate, year);

最後將結果四捨五入至小數點後兩位,並設定到 id="amount" 的文字輸入欄位:

document.getElementById("amount").value = amount.toFixed(2);

完整程式碼

<form onsubmit="calculateCompoundInterest(event)">
🔒

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

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

免費註冊

其他考古題