110 地方特考四等 資訊處理 程式設計概要 考古題詳解
第 一 題25 分
請使用 C、C++、C#、Java 或 Python 程式語言,撰寫一個可以接受整數 array 及一個目標整數值的 twoSum() 方法,此方法會找出 array 中兩個整數值相加結果等於目標整數值的註標位置,並回傳由此兩註標所組成的 array;主程式則負責呼叫 twoSum (dataArray, targetValue) 方法,並顯示結果。您的方法中必需檢查輸入 array 至少有兩個整數值相加結果等於目標整數值,否則回傳 Null/None,同時主程式應測試如下的資料並顯示結果:
測試一:dataArray ,目標值 ,回傳顯示 測試二:dataArray ,目標值 ,回傳顯示 None 或 Null
註:只需找出一組答案。 註:如果無法找出兩個 array 內的整數值加總等於目標值,則回傳 Null or None。 限制:所撰寫的方法內,不可以使用任何程式語言內建或第三方提供的套件,即 python/java 不可以使用 import,C++、C# 不可以使用 using 再加入套件……
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 陣列索引:Python 的陣列索引從 開始。
- Two Sum 問題:在陣列中找出兩個不同位置的元素,使其總和等於目標值。
- 巢狀迴圈:逐一檢查所有可能的兩元素組合。
- 方法回傳值:找到答案時回傳兩個索引組成的陣列;找不到時回傳
None。 - 只需找出一組答案:找到第一組符合條件的索引後即可立即回傳。
本題不是選擇題,因此無選項分析。
解題方法
設陣列為 dataArray,目標值為 targetValue。
使用兩層迴圈:
- 外層索引
i從 開始。 - 內層索引
j從i + 1開始,確保: - 不會使用同一個元素兩次。
- 不會重複檢查相同的索引組合。
- 檢查:
若成立,立即回傳 [i, j]。
若所有組合都檢查完仍未找到,代表不存在符合條件的兩個元素,回傳 None。
可能的索引組合如下:
Python 參考解答
第 二 題25 分
請問如下的 Python 程式正確執行後的結果為何?如有語法或執行時期的錯誤,請說明為那種錯誤,應如何修正,修正後執行的結果為何?
【Loop/Recursive python methods】
def loopGS(aa, rr, nn):
if (isinstance(aa,int) or isinstance(aa,float)) and \
(isinstance(rr,int) or isinstance(rr,float)) and \
(isinstance(nn,int)):
if (nn>=0):
result=0
for ii in range(0, (nn+1)):
result = result + aa*(rr**ii)
else: result = None
else: result = None
return result
def recursiveGS (aa, rr, nn):
if (isinstance(aa,int) or isinstance(aa,float)) and \
(isinstance(rr,int) or isinstance(rr,float)) and \
(isinstance(nn,int)):
if (nn<0): return None
else:
if (nn==0): return aa
else: return (aa*(rr**nn)+recursiveGS(aa,rr,nn-1))
else: return None
【Loop/Recursive python test prog.】
print("\n===== Loop geometric series")
print("GS (a=0.5, r= 2, n= 5 -->", loopGS(0.5, 2, 5))
print("GS (a= 2, r= -2, n= 5 -->", loopGS( 2, -2, 5))
print("GS (a= 1, r= 'a', n= 5 -->", loopGS( 1, 'a', 5))
print("GS (a= 1, r= 2, n= -1 -->", loopGS( 1, 2, -1))
print("\n===== Recursive geometric series")
print("GS (a=0.5, r= 2, n= 5 -->", recursiveGS(0.5, 2, 5))
print("GS (a= 2, r= -2, n= 5 -->", recursiveGS( 2, -2, 5))
print("GS (a= 1, r= 'a', n= 5 -->", recursiveGS( 1, 'a', 5))
print("GS (a= 1, r= 2, n= -1 -->", recursiveGS( 1, 2, -1))
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- Python 函式定義與函式呼叫。
isinstance的資料型態判斷。for迴圈與range。- 遞迴函式的基底條件與遞迴關係。
- 等比級數的計算。
- 不符合條件時回傳
None,以及錯誤與正常回傳值的區別。
本題的等比級數定義為:
其中:
- 為首項。
- 為公比。
- 必須是整數,且 時才進行計算。
一、loopGS 迴圈版本分析
程式邏輯
for ii in range(0, (nn+1)):
result = result + aa*(rr**ii)
range(0, nn+1) 會產生:
因此會累加:
若輸入型態不符合要求,或 ,函式會回傳 None,不會發生例外。
1. loopGS(0.5, 2, 5)
計算:
因此:
GS (a=0.5, r= 2, n= 5 --> 31.5
2. loopGS(2, -2, 5)
計算:
因此:
GS (a= 2, r= -2, n= 5 --> -42
負公比並不會造成錯誤,只是各項正負號交替。
3. loopGS(1, 'a', 5)
rr 的值為字串 'a',不符合:
isinstance(rr, int) or isinstance(rr, float)
因此條件不成立,函式直接執行:
result = None
並回傳 None。
這不是語法錯誤,也不是執行時期錯誤,而是程式設計者預先定義的無效輸入處理。
輸出為:
GS (a= 1, r= 'a', n= 5 --> None
4. loopGS(1, 2, -1)
nn=-1 是整數,型態檢查通過;但:
if (nn >= 0):
條件不成立,因此執行:
result = None
輸出為:
GS (a= 1, r= 2, n= -1 --> None
range(0,0) 即使執行也不會產生內容,但本程式在進入迴圈前已將結果設定為 None。
二、recursiveGS 遞迴版本分析
遞迴邏輯
當 時:
if (nn==0): return aa
因此:
當 時:
return (aa*(rr**nn)+recursiveGS(aa,rr,nn-1))
其遞迴關係為:
這會逐步展開為:
第 三 題30 分
請就如下的 Java 程式,說明程式中各方法(包括建構子)執行的順序,及最後顯示的結果。
註:執行程序說明,如主程式呼叫 MyVaccinePassport 建構子
【繼承關係的三個 classes】
//===== Class for OOP
class Record {
String date, mCode, type;
Record(){}
Record(String dd, String mm, String tt) { date=dd; mCode=mm; type=tt; }
} // End of class MedicalInstitution
abstract class VaccinePassport extends Record{
ArrayList<Record> records = new ArrayList<Record>();
void addVaccinePassport(String dd, String mm, String tt) {
records.add(new Record(dd, mm, tt));
}
String printRecord() {
String ss = "";
for (Record rr : records)
ss += (" --> " + rr.date + " " + rr.mCode + " " + rr.type + "\n");
return ss;
} // End of printRecord()
} // End of class VaccinePassport
class MyVaccinePassport extends VaccinePassport {
String ID = "A0000", name="AAAA";
MyVaccinePassport(String ii, String nn, String dd, String mm, String tt) {
super();
ID = ii;
name = nn;
addVaccinePassport(dd, mm, tt);
} // End of Constructor
void printMyRecord() {
System.out.println("Dear " + ID + ", " + name + "\n" + printRecord());
} // End of printMyRecord()
} // End of class MyVaccinePassport
【OOP test program】
import java.util.ArrayList;
//===== Main Entrance
public class TestOOP_1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyVaccinePassport myVP;
myVP = new MyVaccinePassport("A1234", "Mary", "2021/10/14", "m0001", "AZ");
myVP.addVaccinePassport("2021/11/24", "m0002", "MO");
myVP.printMyRecord();
}
} // End of TestOOP
登入後即可作答並保存紀錄。
核心觀念
本題主要考查 Java 物件導向中的:
- 繼承與建構子呼叫順序。
- 子類別建構子必須先完成父類別建構。
- Java 建構物件時,會先執行父類別部分,再執行子類別的實例變數初始化與建構子本體。
- 方法覆蓋與方法呼叫。
ArrayList儲存物件,以及for-each逐筆走訪資料。- 字串串接與換行字元
\n的輸出效果。
繼承關係如下:
VaccinePassport 繼承 Record,MyVaccinePassport 再繼承 VaccinePassport。
解題方法
判斷建構與方法順序時,依照以下原則:
- 執行子類別建構子時,先執行父類別建構子。
- 若父類別建構子未明確撰寫,編譯器會補上無參數建構子呼叫。
- 父類別建構完成後,才初始化子類別的實例變數。
- 最後執行子類別建構子的本體。
- 方法呼叫則依照主程式由上而下執行。
第一次建立 MyVaccinePassport 物件
主程式執行:
myVP = new MyVaccinePassport(
"A1234", "Mary", "2021/10/14", "m0001", "AZ");
實際執行順序如下。
1. 呼叫 MyVaccinePassport 建構子
MyVaccinePassport(String ii, String nn, String dd, String mm, String tt)
進入建構子後,第一行是:
super;
因此必須先呼叫父類別 VaccinePassport 的無參數建構子。
2. 呼叫 VaccinePassport 建構子
題目未明確撰寫 VaccinePassport,因此 Java 編譯器會提供一個隱含的無參數建構子。
由於 VaccinePassport 繼承 Record,其建構子又會先呼叫:
super;
也就是呼叫 Record。
3. 呼叫 Record 建構子
執行:
Record{}
此建構子沒有任何程式敘述,執行完即返回。
4. 初始化 VaccinePassport 的實例變數
回到 VaccinePassport 後,執行實例變數初始化:
ArrayList<Record> records = new ArrayList<Record>;
此時建立一個空的 ArrayList<Record>,供後續儲存疫苗紀錄。
5. 完成 VaccinePassport 建構子
VaccinePassport 沒有額外的建構子本體,因此建構完成,返回 MyVaccinePassport。
6. 初始化 MyVaccinePassport 的實例變數
執行:
String ID = "A0000";
String name = "AAAA";
此時:
ID = "A0000"
name = "AAAA"
7. 執行 MyVaccinePassport 建構子本體
依序執行:
ID = ii;
因此:
ID = "A1234"
接著執行:
name = nn;
因此:
name = "Mary"
接著呼叫:
addVaccinePassport(dd, mm, tt);
實際參數為:
addVaccinePassport("2021/10/14", "m0001", "AZ");
8. 執行第一次 addVaccinePassport
方法內容為:
records.add(new Record(dd, mm, tt));
先建立新的 Record 物件,因此呼叫:
Record(String dd, String mm, String tt)
參數值為:
dd = "2021/10/14"
mm = "m0001"
tt = "AZ"
執行:
date = dd;
mCode = mm;
type = tt;
建立出的紀錄為:
date = 2021/10/14
mCode = m0001
type = AZ
接著將此 Record 物件加入 records。
此時 records 內容為:
| 順序 | date | mCode | type |
|---|---|---|---|
| 1 | 2021/10/14 | m0001 | AZ |
第一次 MyVaccinePassport 建構子執行完畢。
第二次新增疫苗紀錄
主程式接著執行:
myVP.addVaccinePassport("2021/11/24", "m0002", "MO");
呼叫:
VaccinePassport.addVaccinePassport
此方法執行:
第 四 題20 分
請撰寫一支包含 Javascript 及 HTML 程式碼的 checkLegalForVaccineShot.html 程式,執行後可以呈現如下的頁面,其中「身分證字號」、「健保卡卡號」、及「手機號碼」輸入欄位的長度由 HTML 控制,資料內容則使用 Javascript 檢查,資料內容檢查後,在對應的資料輸入位置右方顯示,「請輸入正確的……」或 "OK" 表示檢查的結果。
註:身分證字號由一碼的英文字母及九碼的數字所組成,如 A123456789 註:健保卡卡號由三組四碼的數字所組成,如 1234-5678-1234 註:手機號碼由 09 加上八碼的數字所組成,如 0912345678
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- HTML 表單與輸入欄位設定。
maxlength控制輸入長度。- JavaScript 讀取表單資料。
- 使用正規表示式(Regular Expression)檢查資料格式。
- 將檢查結果顯示在輸入欄位右方。
依題目規定,格式如下:
- 身分證字號:1 碼英文字母加 9 碼數字。
- 健保卡卡號:3 組,每組 4 碼數字。
- 手機號碼:
09加 8 碼數字,共 10 碼。
本題只要求依指定格式檢查,不要求進一步驗證身分證字號的檢查碼。
解題方法
HTML 使用 maxlength 限制輸入長度:
- 身分證字號:
maxlength="10" - 健保卡卡號的三個欄位:各為
maxlength="4" - 手機號碼:
maxlength="10"
JavaScript 使用正規表示式:
- 身分證字號:
/^[A-Za-z][0-9]{9}$/ - 健保卡卡號:
/^[0-9]{12}$/ - 手機號碼:
/^09[0-9]{8}$/
其中:
^表示字串開頭。$表示字串結尾。[A-Za-z]表示一個英文字母。[0-9]{9}表示 9 碼數字。09表示手機號碼必須以 09 開頭。
健保卡號雖然畫面分成三個欄位,中間有兩個連字號,但檢查時可將三個欄位串接起來,再檢查是否為 12 碼數字。