前言
這學期剛剛接觸面向?qū)ο蟪绦蛟O計,使用的是java語言。在此之前只接觸過c語言。以我目前的學習進程來看二者的差別更多體現(xiàn)在面向?qū)ο蟮钠渲幸粋€基本特性上,即封裝性。在c語言中幾乎所有內(nèi)容都是公開的,java可以有效得規(guī)避這點。
學習的知識點
1.知道了類間關系。面向?qū)ο蟪绦蛟O計中要根據(jù)實際情況合理使用繼承,關聯(lián),聚合,組合,依賴等五類類間關系。選擇合適的類間關系有利于代碼的維護和使用。
2.知道了類的使用。類可以包含屬性和方法。這使得類可以實現(xiàn)單一職責原則。這項原則在程序設計中尤為重要。另外的,設計類時也要注意封裝性,不能盲目得使用public。同時,部分類需要通過實例調(diào)用。
3.學習了java包中的部分方法,知道了導包。為了完成PTA作業(yè),學習了regex,Math等包中的方法,便于處理部分問題。
4.學會了管理數(shù)據(jù)。學習了ArrayList,LinkedList和HashMap的原理和使用。
自我改進的方面
- 增強程序設計的“全局觀念”。設計程序考慮后續(xù)的拓展與維護。
- 拓寬學習方法。對于面向?qū)ο蟮膶W習不能僅局限于學校的學習體系,學習網(wǎng)站和AI大模型也是較好的學習途徑。
三次PTA的難度逐步加大的同時也根據(jù)實際情況增加了越來越多的限制,對學生的應變能力與自學能力有較大要求。
設計分析
第一次PTA大作業(yè):
1)題目要求
7-5 答題判題程序-1
分數(shù) 74
困難
作者 蔡軻
單位 南昌航空大學
設計實現(xiàn)答題程序,模擬一個小型的測試,要求輸入題目信息和答題信息,根據(jù)輸入題目信息中的標準答案判斷答題的結(jié)果。
輸入格式:
程序輸入信息分三部分:
1、題目數(shù)量
格式:整數(shù)數(shù)值,若超過1位最高位不能為0,
樣例:34
2、題目內(nèi)容
一行為一道題,可以輸入多行數(shù)據(jù)。
格式:"#N:"+題號+" "+"#Q:"+題目內(nèi)容+" "#A:"+標準答案
格式約束:題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
樣例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
3、答題信息
答題信息按行輸入,每一行為一組答案,每組答案包含第2部分所有題目的解題答案,答案的順序號與題目題號相對應。
格式:"#A:"+答案內(nèi)容
格式約束:答案數(shù)量與第2部分題目的數(shù)量相同,答案之間以英文空格分隔。
樣例:#A:2 #A:78
2是題號為1的題目的答案
78是題號為2的題目的答案
答題信息以一行"end"標記結(jié)束,"end"之后的信息忽略。
輸出格式:
1、題目數(shù)量
格式:整數(shù)數(shù)值,若超過1位最高位不能為0,
樣例:34
2、答題信息
一行為一道題的答題信息,根據(jù)題目的數(shù)量輸出多行數(shù)據(jù)。
格式:題目內(nèi)容+" ~"+答案
樣例:1+1=~2
2+2= ~4
3、判題信息
判題信息為一行數(shù)據(jù),一條答題記錄每個答案的判斷結(jié)果,答案的先后順序與題目題號相對應。
格式:判題結(jié)果+" "+判題結(jié)果
格式約束:
1、判題結(jié)果輸出只能是true或者false,
2、判題信息的順序與輸入答題信息中的順序相同
樣例:true false true
設計建議:
以下是針對以上題目要求的設計建議,其中的屬性、方法為最小集,實現(xiàn)代碼中可根據(jù)情況添加所需的內(nèi)容:
題目類(用于封裝單個題目的信息):
屬性:題目編號、題目內(nèi)容、標準答案-standardAnswer
方法:數(shù)據(jù)讀寫set\get方法、
判題方法(答案-answer):判斷答案-answer是否符合標準答案-standardAnswer
試卷類(用于封裝整套題目的信息)
屬性:題目列表(題目類的對象集合)、題目數(shù)量
方法:判題方法(題號-num、答案-answer):判斷答案-answer是否符合對應題號的題目標準答案-standardAnswer
保存題目(題號-num、題目-question):將題目保存到題目列表中,保存位置與num要能對應
答卷類(用于封裝答題信息)
屬性:試卷(試卷類的對象)、答案列表(保存每一題的答案)、判題列表(保存每一題的判題結(jié)果true/false)
方法:判題方法(題號-num):判斷答案列表中第num題的結(jié)果是否符合試卷中對應題號的題目標準答案
輸出方法(題號-num):按照題目的格式要求,輸出題號為num的題目的內(nèi)容和答題結(jié)果。
保存一個答案(題號-num,答案-answer):保存題號為num的題目的答題結(jié)果answer。
2)個人設計
由于第一次作業(yè)給出了設計建議,本次作業(yè)按照建議進行設計。
針對題目信息設計了exercise類,其中包含了題號,題目內(nèi)容和正確答案三個屬性。除構造方法等存取類方法外,還設計了一個根據(jù)輸入的答案判斷答案對錯的方法。
`class exercise{
private int NO = 0;//題號
private String Content = "";//題目內(nèi)容
private String standardAnswer = "";//正確答案
public int getNO() {
return NO;
}
public void setNO(int NO) {
this.NO = NO;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
public boolean judge(String answer){//判斷對錯
return answer.equals(this.standardAnswer);
}
}`
針對試卷信息設計了paper類,其中包含了總題數(shù)和題目類數(shù)組兩個屬性。除構造方法等存取類方法外,還設計了一個根據(jù)題目順序和答案判斷對應題目的答案的對錯的方法。
`class paper {
public int sum;//總題數(shù)
public exercise[] exe;//題目數(shù)組
public boolean Judge(int num, String answer) {
return exe[num].judge(answer);
}
public void save(int num, String question) {
exe[num].setNO(num);
exe[num].setContent(question);
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
exe = new exercise[sum + 1];
}
}`
針對答卷信息設計了AnswerPaper類,其中包含了試卷,答案列表和判斷列表三個屬性。只有存取類方法。
`class AnswerPaper {
public paper Paper;//試卷
private String[] answer;//答案列表
private boolean[] judge;//判斷列表
public AnswerPaper(int sum) {
this.answer = new String[sum + 1];
this.judge = new boolean[sum + 1];
}
public void judge(int num) {
this.judge[num] = Paper.exe[num].judge(answer[num]);
}
public void saveAnswer(int num, String answer) {
this.answer[num] = answer;
}
public void setPaper(paper paper) {
Paper = paper;
}
public void setAnswer(String[] answer) {
this.answer = answer;
}
public void setJudge(boolean[] judge) {
this.judge = judge;
}
public String[] getAnswer() {
return answer;
}
public boolean[] getJudge() {
return judge;
}
}`
3)設計分析:
由于本次作業(yè)是第一次大作業(yè),本人對于程序設計經(jīng)驗欠缺,造成了較大的設計缺陷:
- 設計的類中部分屬性為public,這不符合面向?qū)ο蟮姆庋b性。
- 沒有考慮程序的后續(xù)迭代,部分類設計僅適用于當前作業(yè),而在后續(xù)作業(yè)無法繼續(xù)使用。如因為本題給出了總題數(shù),在paper類設計中就簡單得將題目存在以總題數(shù)為長度的數(shù)組中,沒有考慮到后續(xù)題目數(shù)量的確定和試卷中題目的順序。
第二次PTA大作業(yè)
1)題目要求
7-4 答題判題程序-2
分數(shù) 73
困難
作者 蔡軻
單位 南昌航空大學
設計實現(xiàn)答題程序,模擬一個小型的測試,以下粗體字顯示的是在答題判題程序-1基礎上增補或者修改的內(nèi)容。
要求輸入題目信息、試卷信息和答題信息,根據(jù)輸入題目信息中的標準答案判斷答題的結(jié)果。
輸入格式:
程序輸入信息分三種,三種信息可能會打亂順序混合輸入:
1、題目信息
一行為一道題,可輸入多行數(shù)據(jù)(多道題)。
格式:"#N:"+題目編號+" "+"#Q:"+題目內(nèi)容+" "#A:"+標準答案
格式約束:
1、題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
2、允許題目編號有缺失,例如:所有輸入的題號為1、2、5,缺少其中的3號題。此種情況視為正常。
樣例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、試卷信息
一行為一張試卷,可輸入多行數(shù)據(jù)(多張卷)。
格式:"#T:"+試卷號+" "+題目編號+"-"+題目分值
題目編號應與題目信息中的編號對應。
一行信息中可有多項題目編號與分值。
樣例:#T:1 3-5 4-8 5-2
3、答卷信息
答卷信息按行輸入,每一行為一張答卷的答案,每組答案包含某個試卷信息中的題目的解題答案,答案的順序與試卷信息中的題目順序相對應。
格式:"#S:"+試卷號+" "+"#A:"+答案內(nèi)容
格式約束:答案數(shù)量可以不等于試卷信息中題目的數(shù)量,沒有答案的題目計0分,多余的答案直接忽略,答案之間以英文空格分隔。
樣例:#S:1 #A:5 #A:22
1是試卷號
5是1號試卷的順序第1題的題目答案
22是1號試卷的順序第2題的題目答案
答題信息以一行"end"標記結(jié)束,"end"之后的信息忽略。
輸出格式:
1、試卷總分警示
該部分僅當一張試卷的總分分值不等于100分時作提示之用,試卷依然屬于正常試卷,可用于后面的答題。如果總分等于100分,該部分忽略,不輸出。
格式:"alert: full score of test paper"+試卷號+" is not 100 points"
樣例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行為一道題的答題信息,根據(jù)試卷的題目的數(shù)量輸出多行數(shù)據(jù)。
格式:題目內(nèi)容+""+答案++""+判題結(jié)果(true/false)
約束:如果輸入的答案信息少于試卷的題目數(shù)量,答案的題目要輸"answer is null"
樣例:3+2=5true
4+6=~22~false.
answer is null
3、判分信息
判分信息為一行數(shù)據(jù),是一條答題記錄所對應試卷的每道小題的計分以及總分,計分輸出的先后順序與題目題號相對應。
格式:題目得分+" "+....+題目得分+"~"+總分
``
格式約束:
1、沒有輸入答案的題目計0分
2、判題信息的順序與輸入答題信息中的順序相同
樣例:5 8 0~13
根據(jù)輸入的答卷的數(shù)量以上2、3項答卷信息與判分信息將重復輸出。
4、提示錯誤的試卷號
如果答案信息中試卷的編號找不到,則輸出”the test paper number does not exist”,參見樣例9。
設計建議:
參考答題判題程序-1,建議增加答題類,類的內(nèi)容以及類之間的關聯(lián)自行設計。
題目相當于第一次作業(yè)更加復雜:
- 輸入的三種信息可以亂序混合輸入
- 由一張試卷演變成了多張試卷,每張試卷信息都需要存儲
- 存在答卷沒有答案或多余答案的情況
- 新增試卷總分預警
- 空答案的答卷有單獨的輸出情況
- 新增了判分信息的輸出
2)個人設計
針對題目類,本次作業(yè)整體延用了上次作業(yè)的exercise類
`class exercise{
private int NO;//題目編號
private String Content;//題目內(nèi)容
private String standardAnswer;//正確答案
public exercise(int NO, String content, String standardAnswer) {
this.NO = NO;
Content = content;
this.standardAnswer = standardAnswer;
}
public int getNO() {
return NO;
}
public void setNO(int NO) {
this.NO = NO;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
public boolean judge(String answer){//判斷對錯
return answer.equals(this.standardAnswer);
}
}`
針對試卷類,本次作業(yè)與上次相比變化較大。有試卷編號,題目號與分值組成的HashMap,試卷總分和存儲試卷號順序的ArrayList。使用HashMap是為了將題目編號與題目分值相關聯(lián);使用ArrayList是因為本次作業(yè)未給出試卷的題目總數(shù);試卷總分是為了實現(xiàn)試卷總分預警。
`class paper {
private static int NoPaper;//試卷編號
private HashMap<Integer, Integer> ExerciseAndGrade;// key為題目編號,value為題目分值
private int SumGrade = 0;
private ArrayList
public paper(int noPaper) {
NoPaper = noPaper;
ExerciseAndGrade = new HashMap<>(); // 初始化ExerciseAndGrade
}
public void setExerciseAndGrade(int NOEXE, int Grade) {
ExerciseAndGrade.put(NOEXE, Grade);
SumGrade = SumGrade + Grade;
}
public ArrayList<Integer> getEXES() {
return EXES;
}
public void addEXES(int NO) {
EXES.add(NO);
}
public int getSumGrade() {
return SumGrade;
}
public HashMap<Integer, Integer> getExerciseAndGrade() {
return ExerciseAndGrade;
}
}`
針對答卷類,本次作業(yè)對其進行了重新設計。設計了答卷編號和存儲答案的ArrayList兩個屬性。使用ArrayList是因為本次作業(yè)未給出試卷的總題目數(shù)。
`class AnswerPaper {
private int _NoPaper;//答卷編號
private ArrayList
public AnswerPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
Answers = new ArrayList<>(); // 初始化Answers
}
public void setAnswer(String Answer) {
Answers.add(Answer);
}
public int get_NoPaper() {
return _NoPaper;
}
public void set_NoPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
}
public ArrayList<String> getAnswers() {
return Answers;
}
public void setAnswers(String answers) {
Answers.add(answers);
}
}`
在Main類中定義了存儲題號和題目實例的exerciseMap,為HashMap;存儲試卷編號與試卷實例的PaperMap,為HashMap;存儲試卷編號的PaperSum,為ArrayList;存儲答卷實例的answerPaper,為ArrayList。
//題目類 static HashMap<Integer,exercise> exerciseMap=new HashMap<>();//key題號,value題目 //試卷類 static HashMap<Integer,paper> PaperMap=new HashMap<>(); //key編號 value試卷 static ArrayList<Integer> PaperSum = new ArrayList<>();//存試卷編號 //答卷類 static ArrayList<AnswerPaper> answerPaper=new ArrayList<>();//答卷的數(shù)組
在main方法中對于輸入數(shù)據(jù)的處理與上次作業(yè)有較大不同。
由于輸入格式的改變,輸入時先對輸入數(shù)據(jù)關鍵字進行匹配與分類,根據(jù)不同的類別處理信息。
`String Str = "";
while (sc.hasNextLine()) {
Str = sc.nextLine();
if(Str.equals("end")) {
break;
}
if(Str.contains("#N")){
String[] parts = Str.split("#N:| #Q:| #A:");
exercise EXE = new exercise(Integer.parseInt(parts[1]),parts[2],parts[3]);
exerciseMap.put(Integer.parseInt(parts[1]),EXE);
} else if (Str.contains(("#T"))) {
String[] parts = Str.split("#T:|-| ");
paper PAPER = new paper(Integer.parseInt(parts[1]));
for(int i = 2;i < parts.length;i = i + 2) {
PAPER.setExerciseAndGrade(Integer.parseInt(parts[i]),Integer.parseInt(parts[i + 1]));
PAPER.getEXES().add(Integer.parseInt(parts[i]));
}
PaperMap.put(Integer.parseInt(parts[1]),PAPER);
if(!PaperSum.contains(Integer.parseInt(parts[1]))) {
PaperSum.add(Integer.parseInt(parts[1]));
}
} else if(Str.contains("#S")){
String[] parts = Str.split("#S:| #A:");
AnswerPaper Anpaper = new AnswerPaper(Integer.parseInt(parts[1]));
for(int i = 2; i <= parts.length - 1;i ++){
Anpaper.setAnswer(parts[i]);
}
answerPaper.add(Anpaper);
}
}`
3)設計分析
- 吸取上次作業(yè)的教訓,本次作業(yè)對所有屬性都進行了封裝。
- 由于不知道各類信息的具體數(shù)量,本次作業(yè)靈活使用ArrayList處理數(shù)據(jù)。同時,對于部分有聯(lián)系的信息采用了HashMap進行存儲。
- 各類基本實現(xiàn)了單一職責。
- 對于上次作業(yè)的結(jié)構進行了較大改變,使其符合題目要求的同時更好得進行拓展。
第三次PTA大作業(yè)
1)題目要求
7-3 答題判題程序-3
分數(shù) 84
困難
作者 蔡軻
單位 南昌航空大學
設計實現(xiàn)答題程序,模擬一個小型的測試,以下粗體字顯示的是在答題判題程序-2基礎上增補或者修改的內(nèi)容,要求輸入題目信息、試卷信息、答題信息、學生信息、刪除題目信息,根據(jù)輸入題目信息中的標準答案判斷答題的結(jié)果。
輸入格式:
程序輸入信息分五種,信息可能會打亂順序混合輸入。
1、題目信息
題目信息為獨行輸入,一行為一道題,多道題可分多行輸入。
格式:"#N:"+題目編號+" "+"#Q:"+題目內(nèi)容+" "#A:"+標準答案
格式約束:
1、題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
2、允許題目編號有缺失,例如:所有輸入的題號為1、2、5,缺少其中的3號題。此種情況視為正常。
樣例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、試卷信息
試卷信息為獨行輸入,一行為一張試卷,多張卷可分多行輸入數(shù)據(jù)。
格式:"#T:"+試卷號+" "+題目編號+"-"+題目分值+" "+題目編號+"-"+題目分值+...
格式約束:
題目編號應與題目信息中的編號對應。
一行信息中可有多項題目編號與分值。
樣例:#T:1 3-5 4-8 5-2
3、學生信息
學生信息只輸入一行,一行中包括所有學生的信息,每個學生的信息包括學號和姓名,格式如下。
格式:"#X:"+學號+" "+姓名+"-"+學號+" "+姓名....+"-"+學號+" "+姓名
格式約束:
答案數(shù)量可以不等于試卷信息中題目的數(shù)量,沒有答案的題目計0分,多余的答案直接忽略,答案之間以英文空格分隔。
樣例:
#S:1 #A:5 #A:22
1是試卷號
5是1號試卷的順序第1題的題目答案
4、答卷信息
答卷信息按行輸入,每一行為一張答卷的答案,每組答案包含某個試卷信息中的題目的解題答案,答案的順序號與試 卷信息中的題目順序相對應。答卷中:
格式:"#S:"+試卷號+" "+學號+" "+"#A:"+試卷題目的順序號+"-"+答案內(nèi)容+...
格式約束:
答案數(shù)量可以不等于試卷信息中題目的數(shù)量,沒有答案的題目計0分,多余的答案直接忽略,答案之間以英文空格分隔。
答案內(nèi)容可以為空,即””。
答案內(nèi)容中如果首尾有多余的空格,應去除后再進行判斷。
樣例:
#T:1 1-5 3-2 2-5 6-9 4-10 7-3
#S:1 20201103 #A:2-5 #A:6-4
1是試卷號
20201103是學號
2-5中的2是試卷中順序號,5是試卷第2題的答案,即T中3-2的答案
6-4中的6是試卷中順序號,4是試卷第6題的答案,即T中7-3的答案
注意:不要混淆順序號與題號
5、刪除題目信息
刪除題目信息為獨行輸入,每一行為一條刪除信息,多條刪除信息可分多行輸入。該信息用于刪除一道題目信息,題目被刪除之后,引用該題目的試卷依然有效,但被刪除的題目將以0分計,同時在輸出答案時,題目內(nèi)容與答案改為一條失效提示,例如:”the question 2 invalid~0”
格式:"#D:N-"+題目號
格式約束:
題目號與第一項”題目信息”中的題號相對應,不是試卷中的題目順序號。
本題暫不考慮刪除的題號不存在的情況。
樣例:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 1-5 2-8
X:20201103 Tom-20201104 Jack
S:1 20201103 #A:1-5 #A:2-4
D:N-2
end
輸出
alert: full score of test paper1 is not 100 points
1+1=5false
the question 2 invalid~0
20201103 Tom: 0 0~0
答題信息以一行"end"標記結(jié)束,"end"之后的信息忽略。
輸出格式:
1、試卷總分警示
該部分僅當一張試卷的總分分值不等于100分時作提示之用,試卷依然屬于正常試卷,可用于后面的答題。如果總分等于100 分,該部分忽略,不輸出。
格式:"alert: full score of test paper"+試卷號+" is not 100 points"
樣例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行為一道題的答題信息,根據(jù)試卷的題目的數(shù)量輸出多行數(shù)據(jù)。
格式:題目內(nèi)容+""+答案++""+判題結(jié)果(true/false)
約束:如果輸入的答案信息少于試卷的題目數(shù)量,答案的題目要輸"answer is null"
樣例:
3+2=5true
4+6=22false.
answer is null
3、判分信息
判分信息為一行數(shù)據(jù),是一條答題記錄所對應試卷的每道小題的計分以及總分,計分輸出的先后順序與題目題號相對應。
格式:**學號+" "+姓名+": "**+題目得分+" "+....+題目得分+"~"+總分
格式約束:
1、沒有輸入答案的題目、被刪除的題目、答案錯誤的題目計0分
2、判題信息的順序與輸入答題信息中的順序相同
樣例:20201103 Tom: 0 0~0
根據(jù)輸入的答卷的數(shù)量以上2、3項答卷信息與判分信息將重復輸出。
4、被刪除的題目提示信息
當某題目被試卷引用,同時被刪除時,答案中輸出提示信息。樣例見第5種輸入信息“刪除題目信息”。
5、題目引用錯誤提示信息
試卷錯誤地引用了一道不存在題號的試題,在輸出學生答案時,提示”non-existent question~”加答案。例如:
輸入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103 #A:1-4
end
輸出:
alert: full score of test paper1 is not 100 points
non-existent question~0
20201103 Tom: 0~0
如果答案輸出時,一道題目同時出現(xiàn)答案不存在、引用錯誤題號、題目被刪除,只提示一種信息,答案不存在的優(yōu)先級最高,例如:
輸入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103
end
輸出:
alert: full score of test paper1 is not 100 points
answer is null
20201103 Tom: 0~0
6、格式錯誤提示信息
輸入信息只要不符合格式要求,均輸出”wrong format:”+信息內(nèi)容。
例如:wrong format:2 #Q:2+2= #4
7、試卷號引用錯誤提示輸出
如果答卷信息中試卷的編號找不到,則輸出”the test paper number does not exist”,答卷中的答案不用輸出,參見樣例8。
8、學號引用錯誤提示信息
如果答卷中的學號信息不在學生列表中,答案照常輸出,判分時提示錯誤。參見樣例9。
本題暫不考慮出現(xiàn)多張答卷的信息的情況。
題目在上次作業(yè)的基礎上進行迭代:
- 新增了刪除題目信息。被刪除的題目有單獨的輸出方法。
- 新增了學生信息,需要單獨存儲。
- 答卷信息中新增了學生學號的屬性。
- 存在題目引用錯誤的情況。
- 答卷的題目與試卷題目順序相對應。
2)個人設計
題目類與上次作業(yè)相比變化不大
`class exercise{
private int NO;//題目編號
private String Content;//題目內(nèi)容
private String standardAnswer;//正確答案
public exercise(int NO, String content, String standardAnswer) {
this.NO = NO;
Content = content;
this.standardAnswer = standardAnswer;
}
public int getNO() {
return NO;
}
public void setNO(int NO) {
this.NO = NO;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
public boolean judge(String answer){//判斷對錯
return answer.equals(this.standardAnswer);
}
}`
試卷類與上次作業(yè)相比變化不大
`class paper {
private static int NoPaper;//試卷編號
private HashMap<Integer, Integer> ExerciseAndGrade;// key為題目編號,value為題目分值
private int SumGrade = 0;
private ArrayList
public paper(int noPaper) {
NoPaper = noPaper;
ExerciseAndGrade = new HashMap<>(); // 初始化ExerciseAndGrade
}
public void setExerciseAndGrade(int NOEXE, int Grade) {
ExerciseAndGrade.put(NOEXE, Grade);
SumGrade = SumGrade + Grade;
}
public ArrayList<Integer> getEXES() {
return EXES;
}
public void addEXES(int NO) {
EXES.add(NO);
}
public int getSumGrade() {
return SumGrade;
}
public HashMap<Integer, Integer> getExerciseAndGrade() {
return ExerciseAndGrade;
}
}`
答卷類與上次作業(yè)相比變化較大。增加了學生學號與答案順序的屬性,答案順序為ArrayList。答案順序?qū)傩允菫榱诉m應改變的要求。
`class AnswerPaper {
private int _NoPaper;//答卷編號
private HashMap<Integer,String> Answers;//key為答卷的試卷題目順序號,value為答案 // 答案的數(shù)組
private int AnswerStuID;
private ArrayList
public AnswerPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
Answers = new HashMap<>(); // 初始化Answers
AnswerOrder = new ArrayList<>();
}
public void setAnswer(int NO,String Answer) {
Answers.put(NO,Answer);
}
public int get_NoPaper() {
return _NoPaper;
}
public void set_NoPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
}
public HashMap<Integer, String> getAnswers() {
return Answers;
}
public void setAnswers(int NO,String answers) {
Answers.put(NO,answers);
}
public int getAnswerStuID() {
return AnswerStuID;
}
public void setAnswerStuID(int answerStuID) {
AnswerStuID = answerStuID;
}
public ArrayList<Integer> getAnswerOrder() {
return AnswerOrder;
}
public void AnswerOrderAdd(int NO) {
AnswerOrder.add(NO);
}
}`
針對學生信息,新增學生類。包含學生學號與學生姓名兩個屬性。只有基本的存取方法。
`class student {
private int studentID;
private String name;
public student(int studentID, String name) {
this.studentID = studentID;
this.name = name;
}
public student() {
}
public int getStudentID() {
return studentID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}`
針對刪除題目信息,新增刪除題目類。因為被刪除題目在后續(xù)也需要輸出相關的題目信息,不能直接將其刪除,使用新增類來存儲信息。刪除題目信息類只包含被刪除題目的題號一個屬性和基本的存取方法。
`class exerciseBeDeleted {
int delNO;
public exerciseBeDeleted(int delNO) {
this.delNO = delNO;
}
public int getDelNO() {
return delNO;
}
public void setDelNO(int delNO) {
this.delNO = delNO;
}
}`
考慮到題目需要判斷輸入信息是否有效,新增判斷信息是否有效類。包含所需判斷的信息一個屬性和各種輸入方法有效性判斷的方法。
`class judgevalid {
private String input;
public judgevalid(String input) {
this.input = input;
}
public String getInput() {
return input;
}
public boolean exerciseValid() {
String regex = "^#N:\\d+ #Q:.* #A:.*$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean paperValid() {
String regex = "^#T:\\d+(( \\d+-\\d+)+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean studentValid() {
String regex = "^#X:((\\d+) ((\\w+)-(\\d+))+ (\\w+))";//-(\\\\d+) (\\\\w+)(?:-\\\\d+ \\\\w+)*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return true;
//return matcher.matches();
}
public boolean answerPaperValid() {
String regex = "^#S:\\d+ \\d+( #A:\\d*-[^\\s]*)*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean delExeValid() {
String regex = "#D:N-\\d+$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
}`
為了符合題目要求,在Main方法中增加以下方法
- 判斷題目是否被刪除的方法。
public static boolean ExeBeDel(int EXENO) { for(int i = 0;i < delEXE.size();i ++) { if(delEXE.get(i).getDelNO() == EXENO) { return true; } } return false; }
- 精確獲得學生信息在數(shù)組中位置的方法。
public static int AnStuID(int ID,ArrayList<student> Stu) { for(int i = 0;i < Stu.size();i ++) { if(Stu.get(i).getStudentID() == ID) { return i; } } return -1; }
在Main方法中增加了存儲學生實例的studentList,為ArrayList和存儲刪除題目實例的delEXE,為ArrayList
//學生數(shù)組 static ArrayList<student>studentList = new ArrayList<>(); //刪除的題目類 static ArrayList<exerciseBeDeleted> delEXE = new ArrayList<>();//被刪除的題目的數(shù)組
3)設計分析
- 本次作業(yè)在上次作業(yè)延用的基礎上再拓展。
- 在Main類里設計方法,使邏輯更清晰。
踩坑心得
- 在第一次作業(yè)中,程序的結(jié)構設計較差,程序只適用于當前作業(yè),導致后續(xù)作業(yè)需要重新設計,造成巨大麻煩。日后的程序設計需要先設計好結(jié)構。
- 在第一次作業(yè)中沒有對類的屬性進行封裝。日后程序設計要考慮封裝性。
- 在第二次和第三次作業(yè)中數(shù)據(jù)的獲取調(diào)用太多方法,顯得過于冗長難以辨別。日后可以通過設計方法來統(tǒng)一進行部分數(shù)據(jù)的獲取。
for(int j = 0; j < PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().size(); j ++) { //j小于對應答卷的題目數(shù)時 if(answerPaper.get(i).getAnswers().size() < j + 1) { System.out.println("answer is null"); } else { System.out.printf("%s~%s~%s\n",exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j)).getContent(),answerPaper.get(i).getAnswers().get(j),exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j)).judge(answerPaper.get(i).getAnswers().get(j))); } }//答卷的試卷號匹配題目號,題目號匹配題目和答案
改進建議
1. 部分重復冗長的方法調(diào)用,嘗試編寫方法解決。
如以下部分可以設計方法獲取需要的值
for(int j = 0; j < PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().size(); j ++) { //j小于對應答卷的題目數(shù)時 if(answerPaper.get(i).getAnswers().size() < j + 1) { System.out.println("answer is null"); } else { System.out.printf("%s~%s~%s\n",exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j)).getContent(),answerPaper.get(i).getAnswers().get(j),exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j)).judge(answerPaper.get(i).getAnswers().get(j))); } }//答卷的試卷號匹配題目號,題目號匹配題目和答案
2. 將部分內(nèi)容寫成方法避面主函數(shù)過于臃腫。
如main里的輸入存儲可以單獨寫成方法。
`String Str = "";
while (sc.hasNextLine()) {
Str = sc.nextLine();
if(Str.equals("end")) {
break;
}
//題目信息的輸入
if(Str.contains("#N")){
judgevalid Judge = new judgevalid(Str);
if(Judge.exerciseValid()) {
String[] parts = Str.split("#N:| #Q:| #A:");
exercise EXE = new exercise(Integer.parseInt(parts[1]), parts[2], parts[3]);
exerciseMap.put(Integer.parseInt(parts[1]), EXE);
} else {
System.out.printf("wrong format:%s\n",Str);
}
//試卷信息的輸入
} else if (Str.contains(("#T"))) {
judgevalid Judge = new judgevalid(Str);
if(Judge.paperValid()) {
String[] parts = Str.split("#T:|-| ");
paper PAPER = new paper(Integer.parseInt(parts[1]));
for (int i = 2; i < parts.length; i = i + 2) {
PAPER.setExerciseAndGrade(Integer.parseInt(parts[i]), Integer.parseInt(parts[i + 1]));
PAPER.getEXES().add(Integer.parseInt(parts[i]));
}
PaperMap.put(Integer.parseInt(parts[1]), PAPER);
if (!PaperSum.contains(Integer.parseInt(parts[1]))) {
PaperSum.add(Integer.parseInt(parts[1]));
}
} else {
System.out.printf("wrong format:%s\n",Str);
}
//答卷信息的輸入
} else if(Str.contains("#S")) {
judgevalid Judge = new judgevalid(Str);
if(Judge.answerPaperValid()) {
String[] parts = Str.split("#S:| #A:| |-");
AnswerPaper Anpaper = new AnswerPaper(Integer.parseInt(parts[1]));
Anpaper.setAnswerStuID(Integer.parseInt(parts[2]));
for (int i = 3; i < parts.length - 1; i = i + 2) {
Anpaper.setAnswer(Integer.parseInt(parts[i]),parts[i + 1]);
Anpaper.AnswerOrderAdd(Integer.parseInt(parts[i]));
}
answerPaper.add(Anpaper);
} else {
System.out.printf("wrong format:%s\n",Str);
}
//學生信息的輸入
} else if (Str.contains("#X")) {
judgevalid Judge = new judgevalid(Str);
if(Judge.studentValid()) {
String[] parts = Str.split("#X:| |-");
for(int i = 1;i < parts.length - 1;i = i + 2) {
student newStudnt = new student(Integer.parseInt(parts[i]),parts[i + 1]);
studentList.add(newStudnt);
}
} else {
System.out.printf("wrong format:%s\n",Str);
}
//刪除題目信息的輸入
} else if (Str.contains("#D")) {
judgevalid Judge = new judgevalid(Str);
if(Judge.delExeValid()) {
//String[]
String[] parts = Str.split("-");
exerciseBeDeleted delexe = new exerciseBeDeleted(Integer.parseInt(parts[1]));
delEXE.add(delexe);
}
}
}`
3. 保證完成題目要求的同時避免重復代碼。
如輸出時為了保證輸出次序而使用了重復代碼文章來源:http://www.zghlxwxcb.cn/news/detail-855065.html
for(int j = 0; j < PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().size(); j ++) { //j小于對應答卷的題目數(shù)時 if (answerPaper.get(i).getAnswers().size() < j + 1) { System.out.println("answer is null"); } else if (!exerciseMap.containsKey(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j))) { System.out.printf("non-existent question~0\n"); } else if (ExeBeDel(exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).getNO())) { //System.out.printf("the question %d invalid~0\n",exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).getNO()); } else { String exeToprint = exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).getContent(); String answerToprint = answerPaper.get(i).getAnswers().get(answerPaper.get(i).getAnswerOrder().get(j)); boolean judgeToprint = exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).judge(answerPaper.get(i).getAnswers().get(answerPaper.get(i).getAnswerOrder().get(j))); System.out.printf("%s~%s~%s\n",exeToprint,answerToprint,judgeToprint); } } for(int j = 0; j < PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().size(); j ++) { if (answerPaper.get(i).getAnswers().size() < j + 1) { //System.out.println("answer is null"); } else if (!exerciseMap.containsKey(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(j))) { //System.out.printf("non-existent question~0\n"); } else if (ExeBeDel(exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).getNO())) { System.out.printf("the question %d invalid~0\n",exerciseMap.get(PaperMap.get(answerPaper.get(i).get_NoPaper()).getEXES().get(answerPaper.get(i).getAnswerOrder().get(j) - 1)).getNO()); } }
文章來源地址http://www.zghlxwxcb.cn/news/detail-855065.html
到了這里,關于oop第一次博客作業(yè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!