114 一般警察特考三等 警察資訊管理人員類別 物件導向程式設計 考古題詳解

114 年・一般警察特考・三等・警察資訊管理人員類別
試題代碼 物件導向程式設計

第 一 題25 分

針對下列 C++ 程式碼,請說明其輸出與其程式 p.print()、q.split()(Line 28、29)執行之運作流程邏輯;並請說明在 testPattern() 中測試 Pattern 類別 split()(Line 27、29),對於「指令與條件判斷涵蓋度」不足之處。

#include <iostream> #include <string> #include <vector> using namespace std;

class Pattern { public: Pattern(string data) { this->data = data; }

void split(string symbol) {
    int start = 0, stop = 0;
    stop = data.find(symbol);

    while (stop != string::npos) {
        if (stop != start)
            words.push_back(data.substr(start, stop - start));

        start = stop + symbol.size();
        stop = data.find(symbol, start);
    }

    if (start != length)
        words.push_back(data.substr(start));
}

void print() {
    for (auto& s : words)
        cout << s << "#";
    cout << endl;
}

private: string data; vector<string> words; int length; };

void testPattern() { Pattern p("this is a test"); Pattern q("that was so happle");

p.split(" ");
p.print();

q.split("ha");
q.print();

}

int main() { testPattern(); return 0; }

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

這一題的完整詳解

核心觀念

本題考查 C++ 字串與容器的基本操作,以及追蹤函式執行流程:

  • string::find(symbol, start) 從指定位置尋找分隔字串,找不到時回傳 string::npos。
  • string::substr(start, count) 取出從 start 起、長度為 count 的子字串;省略 count 時取到字串結尾。
  • vector::push_back 將切出的字串加入 words。
  • print 依序輸出 words 中的字串,每個字串後接 #,最後換行。

解題方法與執行流程

追蹤 split 時,先記錄 start,再找下一個分隔符位置 stop。找到分隔符後,將 data[start, stop) 放入 words,並把 start 移至分隔符之後;直到找不到分隔符,最後再處理剩餘部分。

p.split(" ") 與 p.print

p 的資料是 "this is a test",空白的位置依序為 4、7、9。

分隔符位置 stop切出的字串更新後的 start
4this5
7is8
9a10

接著找不到下一個空白,split 將 data.substr(10),也就是 test,加入 words。因此 p.print 輸出:

this#is#a#test#

q.split("ha") 與 q.print

q 的資料是 "that was so happle"。子字串 "ha" 出現在索引 2,以及索引 13。

  • 第一次找到索引 2:切出索引 0 到 1 的 "th",接著 start 更新為 2+2=42+2=4。
  • 從索引 4 繼續搜尋,在索引 13 找到 "ha":切出 "t was so ",接著 start 更新為 13+2=1513+2=15。
  • 找不到下一個 "ha",最後將索引 15 之後的 "pple" 加入 words。
🔒

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

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

免費註冊

第 二 題25 分

下列 Java 程式碼計算食物(Food)料理(cook)後,動物(Animal)攝取之卡路里量。請完成統一塑模語言 UML 圖;並說明其執行後的輸出,以及多型(Polymorphism)、封裝(Encapsulation)發生所在之程式碼行數。

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

abstract class Food { public Food(int cal, String type) { this.calorie = cal; this.type = type; }

abstract public void cook(int c);

public String show(int c) {
    String result = type + ":";
    cook(c);
    result += calorie;
    return result;
}

protected int calorie;    // 卡路里
private String type;

}

class Bread extends Food { public Bread(int c, int a) { super(c, "Bread"); additives = a; }

public void cook(int cal) {
    calorie += additives * cal;
}

private int additives;

}

class Beef extends Food { public Beef(int c) { super(c, "Beef"); condiments = c * 2; }

public void cook(int cal) {
    calorie += condiments % cal;
}

private int condiments;

}

class Animal { public Animal(Food f) { food = f; }

public String getCal() {
    return food.show(2);
}

private Food food;

}

public class FoodTest { public static void main(String[] args) { Food f1 = new Bread(3, 2); Food f2 = new Bread(2, 3); Food f3 = new Beef(3);

    Animal a1 = new Animal(f1);
    Animal a2 = new Animal(f2);
    Animal a3 = new Animal(f3);

    System.out.println(a1.getCal());
    System.out.println(a2.getCal());
    System.out.println(a3.getCal());
}

}

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

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

這一題的完整詳解

核心觀念

本題考查:

  1. UML 類別圖與類別繼承。
  2. 抽象類別與抽象方法。
  3. 多型(Polymorphism)與動態繫結。
  4. 封裝(Encapsulation)與存取修飾詞。
  5. Java 整數運算及方法執行流程。

Food 是抽象類別,不能直接建立物件;Bread 與 Beef 繼承 Food,並各自實作 cook(int) 方法。


UML 類別圖

1. Food 抽象類別

<<abstract>>
Food
--------------------------------
# calorie : int
- type : String
--------------------------------
+ Food(cal : int, type : String)
+ {abstract} cook(c : int) : void
+ show(c : int) : String

其中:

  • # 表示 protected。
  • - 表示 private。
  • + 表示 public。

2. Bread 類別

Bread
--------------------------------
- additives : int
--------------------------------
+ Bread(c : int, a : int)
+ cook(cal : int) : void

Bread 繼承 Food。

3. Beef 類別

Beef
--------------------------------
- condiments : int
--------------------------------
+ Beef(c : int)
+ cook(cal : int) : void

Beef 繼承 Food。

4. Animal 類別

Animal
--------------------------------
- food : Food
--------------------------------
+ Animal(f : Food)
+ getCal : String

Animal 持有一個 Food 型態的成員變數,因此具有 Animal 到 Food 的關聯:

Animal 1 ───────── 1 Food

完整的繼承關係為:

 Food
 <<abstract>>
 / \
 / \
 Bread Beef

 Animal ─────── Food

Bread 與 Beef 對 Food 是一般化(Generalization/繼承)關係;Animal 與 Food 是關聯(Association)關係。


解題方法與輸出推導

1. 建立 f1

Food f1 = new Bread(3, 2);

呼叫 Bread 建構子:

  • calorie = 3
  • type = "Bread"
  • additives = 2

執行:

a1.getCal

進入 food.show(2):

String result = type + ":";

得到:

Bread:

接著執行 cook(2)。由於實際物件是 Bread,因此呼叫 Bread.cook(2):

calorie=3+additives×2calorie = 3 + additives \times 2 calorie=3+2×2=7calorie = 3 + 2 \times 2 = 7

所以:

Bread:7

2. 建立 f2

Food f2 = new Bread(2, 3);
🔒

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

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

免費註冊

第 三 題25 分

針對下列 C++ 程式碼,請修正程式碼行數 58「Job jobs ...」的錯誤及修正錯誤後正確執行之輸出;並請說明 Employee 類別 candidate 資料的運作原理,以及程式碼行數 61「e1.arrange()」程式執行之流程。

#include <iostream> #include <string> #include <map> using namespace std;

class Job { public: Job(string _name, int _sa, int _sk) { name = _name; salary = _sa; skill = _sk; employee_name = "None"; }

string getName() { return name; }
int getSalary() { return salary; }
int getSkill() { return skill; }
void hire(string _name) { employee_name = _name; }

void print() {
    cout << name << ":" << employee_name << endl;
}

private: string name; int salary; int skill; string employee_name; };

class Employee { public: Employee(string _name, int _sa, int _sk) { name = _name; salary = _sa; skill = _sk; }

void match(Job *m) {
    if ((m->getSalary() >= salary) && (skill >= m->getSkill())) {
        candidate[m->getName()] = m;
    }
}

void arrange() {
    int score = 0;
    Job *jb, *jb_wanted;

    for (auto c = candidate.begin(); c != candidate.end(); ++c) {
        jb = c->second;    // get value of MAP

        if (jb->getSalary() >= score) {
            score = jb->getSalary();
            jb_wanted = jb;
        }
    }

    jb_wanted->hire(name);
}

string getName() { return name; }

private: string name; int salary; int skill; map<string, Job *> candidate; };

int main() { Employee e1("Tom", 37, 85); Employee e2("John", 35, 75);

Job jobs[] = {
    new Job("RD", 45, 75),
    new Job("Sales", 35, 70),
    new Job("Manager", 55, 80)
};

for (int i = 0; i < 3; i++)
    e1.match(jobs[i]);

e1.arrange();

for (int i = 0; i < 3; i++)
    e2.match(jobs[i]);

e2.arrange();

for (int i = 0; i < 3; i++)
    jobs[i]->print();

return 0;

}

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

這一題的完整詳解

核心觀念

本題考查 C++ 的指標、動態配置物件、map 關聯容器,以及以條件篩選和比較分派工作。

  • new Job(...) 會建立 Job 物件,並回傳指向該物件的 Job*。
  • jobs 是陣列,因此宣告型別必須能存放 Job*。
  • candidate 是 map<string, Job*>:鍵是職務名稱,值是指向職務物件的指標。
  • match 先判斷員工是否符合職務條件,符合才將職務指標放入 candidate。
  • arrange 從候選職務中選出薪資最高者,並把員工姓名記錄到該職務。

修正行數 58

原程式將 new Job(...) 產生的 Job* 放進 Job 陣列,型別不符。應將陣列宣告為 Job*:

Job* jobs[] = {
 new Job("RD", 45, 75),
 new Job("Sales", 35, 70),
 new Job("Manager", 55, 80)
};

此時 jobs[i] 是指標,能傳給 match(Job *m),也能使用 jobs[i]->print 呼叫物件函式。

candidate 資料的運作原理

candidate 宣告如下:

map<string, Job *> candidate;

它以職務名稱作為鍵,以職務指標作為值。match 的判斷條件為:

(m->getSalary >= salary) && (skill >= m->getSkill)

也就是職務薪資必須不低於員工的薪資要求,且員工技能值必須不低於職務要求。符合時執行:

candidate[m->getName] = m;

這會以職務名稱作為鍵,將該職務的指標存入 candidate。map 的鍵會依字典順序排列,因此走訪順序為 Manager、RD、Sales;不過本題 arrange 比較的是薪資,並非依 map 順序決定錄用職務。

e1.arrange 執行流程

e1 是 Tom,薪資要求為 37,技能值為 85。

逐一執行 e1.match(jobs[i]):

職務薪資條件技能條件是否加入 candidate
🔒

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

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

免費註冊

第 四 題25 分

針對下列 C++ 程式碼,請說明其輸出與其 inpuScore()、computeAverage() 執行之運作流程邏輯;並請說明 computeAverage() 設計上的問題。

#include <stdexcept> #include <iostream> #include <string> using namespace std;

class Student { public: Student(string n) { name = n; math_score = eng_score = average = 0; }

void checkSmall(int s) {
    if (s <= 0)
        throw out_of_range("small");
    cout << "ok,";
}

void inpuScore(int m_s, int e_s) {
    try {
        checkSmall(m_s);
        checkSmall(e_s);
        math_score = m_s;
        eng_score = e_s;
    }
    catch (exception &e) {
        cout << e.what() << endl;
    }
}

void computeAverage(int n) {
    try {
        if (n <= 0)
            throw out_of_range("zero");

        average = (math_score + eng_score) / n;
    }
    catch (exception &e) {
        cout << "exc" << endl;
    }
    catch (out_of_range &e) {
        cout << e.what() << endl;
    }
}

void print() {
    cout << name << ":" << average << endl;
}

private: int math_score; // 數學成績 int eng_score; // 英文成績 int average; // 平均成績 string name; };

void test01() { Student stu("John");

stu.inpuScore(0, 0);
stu.inpuScore(100, -1);
stu.inpuScore(100, 90);
stu.print();

}

void test02() { Student stu("Tom");

stu.inpuScore(100, 90);
stu.computeAverage(0);
stu.print();

}

int main() { test01(); test02(); return 0; }

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

這一題的完整詳解

核心觀念

本題考查 C++ 的例外處理與控制流程,重點包括:

  • throw 丟出例外後,該 try 區塊中尚未執行的敘述會略過,控制流程轉到第一個符合型別的 catch。
  • out_of_range 繼承自 exception。因此以 catch (exception &e) 捕捉時,也能捕捉 out_of_range。
  • computeAverage 的兩個 catch 順序有問題:較一般的基底類別 exception 放在前面,會先捕捉 out_of_range,後面的 catch (out_of_range &e) 無法執行,且編譯器通常會將它視為永遠無法到達的處理子句並發出警告。
  • C++ 的整數除法會捨去小數部分;本題未發生有效的正數除法,因此不需進行平均值計算。

解題方法

依序追蹤每次方法呼叫:先確認例外是否被丟出,再看例外發生前哪些敘述已執行、分數成員是否已更新,最後判斷 average 的值。每個 Student 物件建構時,math_score、eng_score 與 average 都先設為 00。

test01 執行流程

  1. 建立 stu("John"),三個整數成員初值皆為 00。
  2. 呼叫 stu.inpuScore(0, 0):
  • checkSmall(0) 因為 0≤00 \leq 0,丟出 out_of_range("small")。
  • 例外發生後,第二次 checkSmall 及兩個分數賦值都不會執行。
  • 例外由 inpuScore 的 catch (exception &e) 捕捉,印出 e.what,也就是 small。
  1. 呼叫 stu.inpuScore(100, -1):
  • checkSmall(100) 通過,先印出 ok,。
  • checkSmall(-1) 丟出 out_of_range("small")。
  • 例外處理使兩個分數賦值都不執行;即使數學成績檢查通過,math_score 仍維持原值 00。
  • catch 印出 small。
  1. 呼叫 stu.inpuScore(100, 90):
  • 兩次檢查都通過,各印出一次 ok,。
  • 接著才將 math_score 設為 100100、eng_score 設為 9090。
  1. average 從未在 test01 中計算,仍是 00。print 印出 John:0。

test02 執行流程

  1. 建立 stu("Tom"),三個整數成員初值皆為 00。
  2. stu.inpuScore(100, 90) 的兩次檢查都通過,印出 ok,ok,,並將兩科成績設為 100100 與 9090。
🔒

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

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

免費註冊

其他考古題

警察資訊管理人員類別《物件導向程式設計》其他年度