OO第一次部落格作業
前言
這是Java學習以來的第一次部落格作業,也是我第一次回過頭來對自己Java的階段性學習做出一個系統性的總結。總的來說做的還有很多的不足,需要多加改進。
在前三次題目集中,我們進行了答題判題程式的書寫,前兩次的題目還比較平常,但第三次的題目引入了錯誤格式的情形,對我的答題造成了不小的阻礙。
在前兩次作業中,由於對類和類間關係的瞭解不夠深入,導致程式碼寫的十分混亂,也沒有遵循單一職責原則。只定義了簡單的三個類,使得程式碼沒有遵循單一職責原則。
1.題量方面
三次PTA說實話題量其實都不算大,只是說最後一題的難度較大導致需要花費較多時間解決。但平心而論如果足夠投入的話就算不能全部完成但拿到高分也是沒有問題的
2.知識點方面
第一次PTA作業主要考察了類和Java陣列的基本運用,題目較為簡單
第二次PTA作業進一步考察了類的運用,還加入了java連結串列的知識點
第三次PTA作業加入了封裝性的概念,還引入了Java中的日期類。最後一道成績判定題則需要運用正規表示式的知識點來進行匹配
設計與分析
第一次PTA:
設計實現答題程式,模擬一個小型的測試,要求輸入題目資訊和答題資訊,根據輸入題目資訊中的標準答案判斷答題的結果。
輸入格式:
程式輸入資訊分三部分:
1、題目數量
格式:整數數值,若超過1位最高位不能為0,
樣例:34
2、題目內容
一行為一道題,可以輸入多行資料。
格式:"#N:"+題號+" "+"#Q:"+題目內容+" "#A:"+標準答案
格式約束:題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
樣例:
\#N:1 #Q:1+1= #A:2
\#N:2 #Q:2+2= #A:4
3、答題資訊
答題資訊按行輸入,每一行為一組答案,每組答案包含第2部分所有題目的解題答案,答案的順序號與題目題號相對應。
格式:"#A:"+答案內容
格式約束:答案數量與第2部分題目的數量相同,答案之間以英文空格分隔。
樣例:
\#A:2 #A:78
2是題號為1的題目的答案
8是題號為2的題目的答案
答題資訊以一行"end"標記結束,"end"之後的資訊忽略。
輸出格式:
1、題目數量
格式:整數數值,若超過1位最高位不能為0,
樣例:34
2、答題資訊
一行為一道題的答題資訊,根據題目的數量輸出多行資料。
格式:題目內容+" ~"+答案
樣例:
1+1=~2
2+2= ~4
3、判題資訊
判題資訊為一行資料,一條答題記錄每個答案的判斷結果,答案的先後順序與題目題號相對應。
格式:判題結果+" "+判題結果
格式約束:
1、判題結果輸出只能是true或者false,
2、判題資訊的順序與輸入答題資訊中的順序相同
樣例:
true false true
輸入樣例1:
單個題目。例如:
1
\#N:1 #Q:1+1= #A:2
\#A:2
end
輸出樣例1:
在這裡給出相應的輸出。例如:
1+1=~2
true
輸入樣例2:
單個題目。例如:
1
\#N:1 #Q:1+1= #A:2
\#A:4
end
輸出樣例2:
在這裡給出相應的輸出。例如:
1+1=~4
false
輸入樣例3:
多個題目。例如:
2
\#N:1 #Q:1+1= #A:2
\#N:2 #Q:2+2= #A:4
\#A:2 #A:4
end
輸出樣例3:
在這裡給出相應的輸出。例如:
1+1=~2
2+2=~4
true true
輸入樣例4:
多個題目。例如:
2
\#N:1 #Q:1+1= #A:2
\#N:2 #Q:2+2= #A:4
\#A:2 #A:2
end
輸出樣例4:
在這裡給出相應的輸出。例如:
1+1=~2
2+2=~2
true false
輸入樣例5:
多個題目,題號順序與輸入順序不同。例如:
2
\#N:2 #Q:1+1= #A:2
\#N:1 #Q:5+5= #A:10
\#A:10 #A:2
end
輸出樣例5:
在這裡給出相應的輸出。例如:
5+5=~10
1+1=~2
true true
輸入樣例6:
含多餘的空格符。例如:
1
\#N:1 #Q: The starting point of the Long March is \#A:ruijin
\#A:ruijin
end
輸出樣例6:
在這裡給出相應的輸出。例如:
The starting point of the Long March is~ruijin
true
輸入樣例7:
含多餘的空格符。例如:
1
\#N: 1 #Q: 5 +5= #A:10
\#A:10
end
輸出樣例7:
在這裡給出相應的輸出。例如:
5 +5=~10
true
類圖分析
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = Integer.parseInt(input.nextLine());//使換行
//題目和答案
ArrayList<Question> questions = new ArrayList<>();
String body;
String content = null;
String num = null;
String answer = null;
for (int i = 0; i < n; i++) {
body = input.nextLine();
String[] parts = body.split("#N:|#Q:|#A:");
if (parts.length > 1) {
num = parts[1].trim();
content = parts[2].trim();
answer = parts[3].trim();
}
questions.add(new Question(num, content, answer));
}
//輸入標答
Paper paper = new Paper(questions, n);
ArrayList<String> standardAnswers = new ArrayList<>();
for (int i = 0; i < n; i++) {
String stand = input.next();
String[] parts = stand.split("#A:");
standardAnswers.add(parts[1]);
}
//排序
paper.sort();
//進行判題
ArrayList<Boolean> judgements = new ArrayList<>();
for(int i=0;i<n;i++){
judgements.add(paper.judge(i,standardAnswers.get(i)));
}
AnswerPaper answerpaper = new AnswerPaper(paper, standardAnswers, judgements);
//輸出答案
for(int i=0;i<n;i++){
answerpaper.printOut(i);
}
for (int i = 0; i < n; i++) {//輸出正誤
System.out.printf("%b", judgements.get(i));
if (i < n - 1) {
System.out.printf(" ");
}
}
String flag = input.next();
if(flag.equals("end")) {
System.exit(0);
}
}
}
class Question {
private String num;
private String content;
private String answer;
public void setAnswer(String answer) {
this.answer = answer;
}
public void setContent(String content) {
this.content = content;
}
public void setNum(String num) {
this.num = num;
}
public String getAnswer() {
return answer;
}
public String getContent() {
return content;
}
public String getNum() {
return num;
}
public Question() {
}
public Question(String num, String content, String answer) {
this.num = num;
this.content = content;
this.answer = answer;
}
public Boolean judge(String standardAnswer) {
return standardAnswer.equals(answer);
}
}
class Paper {
public void setAmount(int amount) {
this.amount = amount;
}
public void setQuestions(ArrayList<Question> questions) {
this.questions = questions;
}
public int getAmount() {
return amount;
}
public ArrayList<Question> getQuestions() {
return questions;
}
private ArrayList<Question> questions;
private int amount;
public Paper(ArrayList<Question> questions, int amount) {
this.questions = questions;
this.amount = amount;
}
public Paper() {
}
public Boolean judge(int num,String answer) {
return questions.get(num).judge(answer);
}
public void sort(){
for(int i=1;i<=getAmount();i++){
for(int j=i;j<=getAmount();j++){
if(Integer.parseInt(getQuestions().get(j-1).getNum())==i){
Question temp=getQuestions().get(i-1);
getQuestions().set(i-1,getQuestions().get(j-1));
getQuestions().set(j-1,temp);
}
}
}
}
}
class AnswerPaper {
public Paper getPaper() {
return paper;
}
private Paper paper;
private ArrayList<String> standardAnswers;
private ArrayList<Boolean> judgements;
public AnswerPaper(Paper paper, ArrayList<String> standardAnswers, ArrayList<Boolean> judgements) {
this.paper = paper;
this.standardAnswers = standardAnswers;
this.judgements = judgements;
}
public AnswerPaper() {
}
public void printOut(int i) {
System.out.println(getPaper().getQuestions().get(i).getContent()+"~"+standardAnswers.get(i));
}
}
SourceMonitor分析結果如下
反思
由圖我們不難看出,程式碼的主要問題在於複雜度較高。我認為這主要是由於當時對於類的運用不夠熟練,對於單一職責原則的應用也不到位。主函式承擔了除輸入輸出外的其他許多功能所導致的。但由於第一次作業較為簡單所以函式深度並未較高
第二次PTA
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-1基礎上增補或者修改的內容。
要求輸入題目資訊、試卷資訊和答題資訊,根據輸入題目資訊中的標準答案判斷答題的結果。
輸入格式:
程式輸入資訊分三種,三種資訊可能會打亂順序混合輸入:
1、題目資訊
一行為一道題,可輸入多行資料(多道題)。
格式:"#N:"+題目編號+" "+"#Q:"+題目內容+" "#A:"+標準答案
格式約束:
1、題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
2、允許題目編號有缺失,例如:所有輸入的題號為1、2、5,缺少其中的3號題。此種情況視為正常。
樣例:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、試卷資訊
一行為一張試卷,可輸入多行資料(多張卷)。
格式:"#T:"+試卷號+" "+題目編號+"-"+題目分值
題目編號應與題目資訊中的編號對應。
一行資訊中可有多項題目編號與分值。
樣例:
#T:1 3-5 4-8 5-2
3、答卷資訊
答卷資訊按行輸入,每一行為一張答卷的答案,每組答案包含某個試卷資訊中的題目的解題答案,答案的順序與試卷資訊中的題目順序相對應。
格式:"#S:"+試卷號+" "+"#A:"+答案內容
格式約束:答案數量可以不等於試卷資訊中題目的數量,沒有答案的題目計0分,多餘的答案直接忽略,答案之間以英文空格分隔。
樣例:
#S:1 #A:5 #A:22
1是試卷號
5是1號試卷的順序第1題的題目答案
22是1號試卷的順序第2題的題目答案
答題資訊以一行"end"標記結束,"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、答卷資訊
一行為一道題的答題資訊,根據試卷的題目的數量輸出多行資料。
格式:題目內容+""+答案++""+判題結果(true/false)
約束:如果輸入的答案資訊少於試卷的題目數量,答案的題目要輸"answer is null"
樣例:
3+2=~5~true
4+6=~22~false.
answer is null
3、判分資訊
判分資訊為一行資料,是一條答題記錄所對應試卷的每道小題的計分以及總分,計分輸出的先後順序與題目題號相對應。
格式:題目得分+" "+....+題目得分+"~"+總分
格式約束:
1、沒有輸入答案的題目計0分
2、判題資訊的順序與輸入答題資訊中的順序相同
樣例:5 8 0~13
根據輸入的答卷的數量以上2、3項答卷資訊與判分資訊將重複輸出。
4、提示錯誤的試卷號
如果答案資訊中試卷的編號找不到,則輸出”the test paper number does not exist”,參見樣例9。
設計建議:
參考答題判題程式-1,建議增加答題類,類的內容以及類之間的關聯自行設計。
輸入樣例1:
一張試卷一張答卷。試卷滿分不等於100。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#S:1 #A:5 #A:22
end
輸出樣例1:
在這裡給出相應的輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
2+2=~22~false
0 0~0
輸入樣例2:
一張試卷一張答卷。試卷滿分不等於100。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-70 2-30
#S:1 #A:5 #A:22
end
輸出樣例2:
在這裡給出相應的輸出。例如:
1+1=~5~false
2+2=~22~false
0 0~0
輸入樣例3:
一張試卷、一張答卷。各類資訊混合輸入。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-70 2-30
#N:3 #Q:3+2= #A:5
#S:1 #A:5 #A:4
end
輸出樣例:
在這裡給出相應的輸出。例如:
1+1=~5~false
2+2=~4~true
0 30~30
輸入樣例4:
試卷題目的順序與題號不一致。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 2-70 1-30
#N:3 #Q:3+2= #A:5
#S:1 #A:5 #A:22
end
輸出樣例:
在這裡給出相應的輸出。例如:
2+2=~5~false
1+1=~22~false
0 0~0
輸入樣例5:
亂序輸入。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-70 2-30
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
end
輸出樣例:
在這裡給出相應的輸出。例如:
3+2=~5~true
2+2=~22~false
70 0~70
輸入樣例6:
亂序輸入+兩份答卷。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-70 2-30
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#S:1 #A:5 #A:4
end
輸出樣例:
在這裡給出相應的輸出。例如:
3+2=~5~true
2+2=~22~false
70 0~70
3+2=~5~true
2+2=~4~true
70 30~100
輸入樣例7:
亂序輸入+分值不足100+兩份答卷。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#S:1 #A:5 #A:4
end
輸出樣例:
在這裡給出相應的輸出。例如:
alert: full score of test paper1 is not 100 points
3+2=~5~true
2+2=~22~false
7 0~7
3+2=~5~true
2+2=~4~true
7 6~13
輸入樣例8:
亂序輸入+分值不足100+兩份答卷+答卷缺失部分答案。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#T:2 2-5 1-3 3-2
#S:2 #A:5 #A:4
end
輸出樣例:
在這裡給出相應的輸出。例如:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=~5~true
2+2=~22~false
7 0~7
2+2=~5~false
1+1=~4~false
answer is null
0 0 0~0
輸入樣例9:
亂序輸入+分值不足100+兩份答卷+無效的試卷號。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:3 #A:5 #A:4
end
輸出樣例:
在這裡給出相應的輸出。例如:
alert: full score of test paper1 is not 100 points
The test paper number does not exist
類圖分析
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<String> N = new ArrayList<>();
ArrayList<String> T = new ArrayList<>();
ArrayList<String> S = new ArrayList<>();
//輸入所有資料並分類
while(true){
String str=input.nextLine();
if(str.contains("#N:")){
N.add(str);
}
if(str.contains("#T:")){
T.add(str);
}
if (str.contains("#S:")){
S.add(str);
}
if(str.equals("end")){
break;
}
}
//對N進行處理
ArrayList<Question> questions = new ArrayList<>();
String body;
String content = null;
String num = null;
String answer = null;
for (int i = 0; i < N.size(); i++) {
String[] parts = N.get(i).split("#N:|#Q:|#A:");
num = parts[1].trim();
content = parts[2].trim();
answer = parts[3].trim();
questions.add(new Question(num, content, answer));
}
//排序
int maxnum=0;
for(int i=0;i<questions.size();i++){
if(Integer.parseInt(questions.get(i).getNum())>maxnum){
maxnum=Integer.parseInt(questions.get(i).getNum());
}
}
boolean[] judge=new boolean[maxnum];
for(int i=0;i<questions.size();i++){
judge[Integer.parseInt(questions.get(i).getNum())-1]=true;
}
for(int i=0;i<maxnum;i++){
if(!judge[i]){
num = String.valueOf(i);
questions.add(new Question(num, content, answer));
}
}
for(int i = 0;i < questions.size()-1;i++){
for(int j = 0;j < questions.size() - i - 1;j++){
if(Integer.parseInt(questions.get(j).getNum()) > Integer.parseInt(questions.get(j+1).getNum())){
Question temp = questions.get(j);
questions.set(j,questions.get(j+1));
questions.set(j+1,temp);
}
}
}
//對T進行處理
ArrayList<Paper> papers = new ArrayList<>();
String score;
for(int i=0;i<T.size();i++){
String[] parts = T.get(i).split("#T:|\\s+|-");
ArrayList<String> nunOfQuestions = new ArrayList<>();
ArrayList<String> scoreOfQuestions = new ArrayList<>();
for(int j = 0;j < parts.length - 3;j=j+2){
num=parts[j+2].trim();
score=parts[j+3].trim();
nunOfQuestions.add(num);
scoreOfQuestions.add(score);
}
Paper paper=new Paper(parts[1].trim(),nunOfQuestions,scoreOfQuestions,questions);
papers.add(paper);
}
//對S進行處理
ArrayList<Answerpaper> answerpapers = new ArrayList<>();
ArrayList<String> myAnswers = new ArrayList<>();
String myAnswer;
for(int i = 0;i < S.size();i++){
String[] parts = S.get(i).split("#S:|#A:");
for(int j=0;j<parts.length-2;j++){
myAnswer=parts[j+2].trim();
myAnswers.add(myAnswer);
}
Answerpaper answerpaper=new Answerpaper(parts[1].trim(),myAnswers,papers);
answerpapers.add(answerpaper);
}
//判斷試卷總分
for(int i=0;i<papers.size();i++){
int j=i+1;
if(!papers.get(i).fullScore()) {
System.out.println("alert: full score of test paper" + j + " is not 100 points");
}
}
//輸出答卷資訊(題目內容加判斷正誤)
int m=0,n=papers.get(0).getNumOfQuestions().size();
for(int i=0;i<answerpapers.size();i++) {
//先判斷答卷是否匹配試卷
int f=0;
for(int j=0;j<papers.size();j++){
if(answerpapers.get(i).getNumOfAnswerpaper().equals(papers.get(j).getNumOfPaper())){
f=1;
break;
}
}
if(f==0){
if (i < papers.size()) {
m += papers.get(i).getNumOfQuestions().size();
}
if (i + 1 < papers.size()) {
n += papers.get(i + 1).getNumOfQuestions().size();
} else if (i < papers.size()) {
n += papers.get(i).getNumOfQuestions().size();
}
System.out.println("The test paper number does not exist");
continue;
}
boolean[] flag = new boolean[papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getQuestions().size()];
for (int j = m; j < n; j++) {
if (j < answerpapers.get(i).getMyAnswers().size()) {
double t = j / (i + 1.0);
if (t == j / (i + 1) && i > 0) {
t--;
}
System.out.print(questions.get(Integer.parseInt(papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getNumOfQuestions().get((int) t)) - 1).getContent());
System.out.print("~");
System.out.print(answerpapers.get(i).getMyAnswers().get(j));
System.out.print("~");
if (questions.get(Integer.parseInt(papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getNumOfQuestions().get((int) t)) - 1).getStandAnswer().equals(answerpapers.get(i).getMyAnswers().get(j))) {
System.out.println("true");
flag[(int) t] = true;
} else {
System.out.println("false");
flag[(int) t] = false;
}
} else
System.out.println("answer is null");
}
if (i < papers.size()) {
m += papers.get(i).getNumOfQuestions().size();
}
if (i + 1 < papers.size()) {
n += papers.get(i + 1).getNumOfQuestions().size();
} else if (i < papers.size()) {
n += papers.get(i).getNumOfQuestions().size();
}
int grade = 0;
for (int k = 0; k < papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getNumOfQuestions().size(); k++) {
if (k != 0)
System.out.print(" ");
if (flag[k]) {
grade += Integer.parseInt(papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getScoreOfQuestions().get(k));
System.out.print(papers.get(Integer.parseInt(answerpapers.get(i).getNumOfAnswerpaper()) - 1).getScoreOfQuestions().get(k));
} else
System.out.print("0");
}
System.out.print("~");
System.out.println(grade);
}
}
}
//////////////////////////////// 分界線 ////////////////////////////////
class Question {//題庫
private String num;
private String content;
private String StandAnswer;
public void setStandAnswer(String standAnswer) {
this.StandAnswer = standAnswer;
}
public void setContent(String content) {
this.content = content;
}
public void setNum(String num) {
this.num = num;
}
public String getStandAnswer() {
return StandAnswer;
}
public String getContent() {
return content;
}
public String getNum() {
return num;
}
public Question() {
}
public Question(String num, String content, String StandAnswer) {
this.num = num;
this.content = content;
this.StandAnswer = StandAnswer;
}
}
class Paper{//試卷
private String numOfPaper;
private ArrayList<String> numOfQuestions;
private ArrayList<String> scoreOfQuestions;
private ArrayList<Question> questions;
public ArrayList<Question> getQuestions() {
return questions;
}
public ArrayList<String> getScoreOfQuestions() {
return scoreOfQuestions;
}
public ArrayList<String> getNumOfQuestions() {
return numOfQuestions;
}
public String getNumOfPaper() {
return numOfPaper;
}
public Paper(String numOfPaper, ArrayList<String> numOfQuestions, ArrayList<String> scoreOfQuestions, ArrayList<Question> questions) {
this.numOfPaper = numOfPaper;
this.numOfQuestions = numOfQuestions;
this.scoreOfQuestions = scoreOfQuestions;
this.questions = questions;
}
public Paper() {
}
public boolean fullScore(){
int sum=0;
for(int i=0;i<scoreOfQuestions.size();i++)
sum+=Integer.parseInt(scoreOfQuestions.get(i));
if(sum==100)
return true;
else
return false;
}
}
class Answerpaper{//答卷
private String numOfAnswerpaper;
private ArrayList<String> myAnswers;
private ArrayList<Paper> papers;
public ArrayList<Paper> getPapers() {
return papers;
}
public ArrayList<String> getMyAnswers() {
return myAnswers;
}
public String getNumOfAnswerpaper() {
return numOfAnswerpaper;
}
public Answerpaper(String numOfAnswerpaper, ArrayList<String> myAnswers, ArrayList<Paper> papers) {
this.numOfAnswerpaper = numOfAnswerpaper;
this.myAnswers = myAnswers;
this.papers = papers;
}
public Answerpaper() {
}
}
反思
其實這裡不難看出,這次的程式碼寫的很差。無論是程式碼的複雜度、深度都遠超出了正常情況。這主要是因為那個時候對於類的理解沒有跟上題目迭代的速度。思路也沒有開啟,沒想到應該使用部分代理類。於是就運用了與前一次作業相同的設計,只是在類中和主函式中進行了部分修改。尤其是主函式,為了達到題目的要求,我在主函式中加入了大量本應該在現有的類甚至是應該新建類中實現的方法。這也就導致了程式碼的混亂。也為下一次作業帶來了不小的麻煩。
第三次作業
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-2基礎上增補或者修改的內容,要求輸入題目資訊、試卷資訊、答題資訊、學生資訊、刪除題目資訊,根據輸入題目資訊中的標準答案判斷答題的結果。
輸入格式:
程式輸入資訊分五種,資訊可能會打亂順序混合輸入。
1、題目資訊
題目資訊為獨行輸入,一行為一道題,多道題可分多行輸入。
格式:"#N:"+題目編號+" "+"#Q:"+題目內容+" "#A:"+標準答案
格式約束:
1、題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
2、允許題目編號有缺失,例如:所有輸入的題號為1、2、5,缺少其中的3號題。此種情況視為正常。
樣例:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、試卷資訊
試卷資訊為獨行輸入,一行為一張試卷,多張卷可分多行輸入資料。
格式:"#T:"+試卷號+" "+題目編號+"-"+題目分值+" "+題目編號+"-"+題目分值+...
格式約束:
題目編號應與題目資訊中的編號對應。
一行資訊中可有多項題目編號與分值。
樣例:
#T:1 3-5 4-8 5-2
3、學生資訊
學生資訊只輸入一行,一行中包括所有學生的資訊,每個學生的資訊包括學號和姓名,格式如下。
格式:"#X:"+學號+" "+姓名+"-"+學號+" "+姓名....+"-"+學號+" "+姓名
格式約束:
答案數量可以不等於試卷資訊中題目的數量,沒有答案的題目計0分,多餘的答案直接忽略,答案之間以英文空格分隔。
樣例:
#S:1 #A:5 #A:22
1是試卷號
5是1號試卷的順序第1題的題目答案
4、答卷資訊
答卷資訊按行輸入,每一行為一張答卷的答案,每組答案包含某個試卷資訊中的題目的解題答案,答案的順序號與試 卷資訊中的題目順序相對應。答卷中:
格式:"#S:"+試卷號+" "+學號+" "+"#A:"+試卷題目的順序號+"-"+答案內容+...
格式約束:
答案數量可以不等於試卷資訊中題目的數量,沒有答案的題目計0分,多餘的答案直接忽略,答案之間以英文空格分隔。
答案內容可以為空,即””。
答案內容中如果首尾有多餘的空格,應去除後再進行判斷。
樣例:
#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分計,同時在輸出答案時,題目內容與答案改為一條失效提示,例如:”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=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
答題資訊以一行"end"標記結束,"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、答卷資訊
一行為一道題的答題資訊,根據試卷的題目的數量輸出多行資料。
格式:題目內容+""+答案++""+判題結果(true/false)
約束:如果輸入的答案資訊少於試卷的題目數量,每一個缺失答案的題目都要輸出"answer is null" 。
樣例:
3+2=~5~true
4+6=~22~false.
answer is null
3、判分資訊
判分資訊為一行資料,是一條答題記錄所對應試卷的每道小題的計分以及總分,計分輸出的先後順序與題目題號相對應。
格式:學號+" "+姓名+": "+題目得分+" "+....+題目得分+"~"+總分
格式約束:
1、沒有輸入答案的題目、被刪除的題目、答案錯誤的題目計0分
2、判題資訊的順序與輸入答題資訊中的順序相同
樣例:20201103 Tom: 0 0~0
根據輸入的答卷的數量以上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
如果答案輸出時,一道題目同時出現答案不存在、引用錯誤題號、題目被刪除,只提示一種資訊,答案不存在的優先順序最高,例如:
輸入:
#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:”+資訊內容。
例如:wrong format:2 #Q:2+2= #4
7、試卷號引用錯誤提示輸出
如果答卷資訊中試卷的編號找不到,則輸出”the test paper number does not exist”,答卷中的答案不用輸出,參見樣例8。
8、學號引用錯誤提示資訊
如果答卷中的學號資訊不在學生列表中,答案照常輸出,判分時提示錯誤。參見樣例9。
本題暫不考慮出現多張答卷的資訊的情況。
輸入樣例1:
簡單輸入,不含刪除題目資訊。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-5
end
輸出樣例1:
在這裡給出相應的輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 Tom: 0~0
輸入樣例2:
簡單輸入,答卷中含多餘題目資訊(忽略不計)。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-2 #A:2-3
end
輸出樣例3
簡單測試,含刪除題目資訊。例如:
alert: full score of test paper1 is not 100 points
1+1=~2~true
20201103 Tom: 5~5
輸入樣例3:
簡單測試,含刪除題目資訊。例如:
#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-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
輸出樣例3:
在這裡給出相應的輸出,第二題由於被刪除,輸出題目失效提示。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
輸入樣例4:
簡單測試,含試卷無效題目的引用資訊以及刪除題目資訊(由於題目本身無效,忽略)。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
輸出樣例4:
輸出不存在的題目提示資訊。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
non-existent question~0
20201103 Tom: 0 0~0
輸入樣例5:
綜合測試,含錯誤格式輸入、有效刪除以及無效題目引用資訊。例如:
#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
輸出樣例5:
在這裡給出相應的輸出。例如:
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
the question 2 invalid~0
20201103 Tom: 0 0~0
輸入樣例6:
綜合測試,含錯誤格式輸入、有效刪除、無效題目引用資訊以及答案沒有輸入的情況。例如:
#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5
#D:N-2
end
輸出樣例6:
答案沒有輸入的優先順序最高。例如:
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
answer is null
20201103 Tom: 0 0~0
輸入樣例7:
綜合測試,正常輸入,含刪除資訊。例如:
#N:2 #Q:2+2= #A:4
#N:1 #Q:1+1= #A:2
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:2-4 #A:1-5
#D:N-2
end
輸出樣例7:
例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
輸入樣例8:
綜合測試,無效的試卷引用。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:2 20201103 #A:1-5 #A:2-4
end
輸出樣例8:
例如:
alert: full score of test paper1 is not 100 points
The test paper number does not exist
輸入樣例9:
無效的學號引用。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201106 Tom
#S:1 20201103 #A:1-5 #A:2-4
end
輸出樣例9:
答案照常輸出,判分時提示錯誤。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 not found
輸入樣例10:
資訊可打亂順序輸入:序號不是按大小排列,各類資訊交錯輸入。但本題不考慮引用的題目在被引用的資訊之後出現的情況(如試卷引用的所有題目應該在試卷資訊之前輸入),所有引用的資料應該在被引用的資訊之前給出。例如:
#N:3 #Q:中國第一顆原子彈的爆炸時間 #A:1964.10.16
#N:1 #Q:1+1= #A:2
#X:20201103 Tom-20201104 Jack-20201105 Www
#T:1 1-5 3-8
#N:2 #Q:2+2= #A:4
#S:1 20201103 #A:1-5 #A:2-4
end
輸出樣例10:
答案按試卷中的題目順序輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
中國第一顆原子彈的爆炸時間~4~false
20201103 Tom: 0 0~0
類圖分析
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
GatMassage gatMassage = new GatMassage();
gatMassage.getDate();
ArrayList<Question> questions=gatMassage.treatN();
Stone stone=new Stone(questions);//建立題庫
stone.sort();//此處新增排序
ArrayList<Paper> papers=gatMassage.treatT();//建立試卷集
ArrayList<Student> students=gatMassage.treatX();//建立學生集
ArrayList<Respond> responds=gatMassage.treatS();//建立答卷集
ArrayList<Integer> deletes=gatMassage.treatD();//建立刪除集
stone=new Stone(questions,deletes,stone.getExistOfQuestions());//引入刪除資訊
stone.delete();//此處新增刪除
gatMassage.treaF();//輸出錯誤格式資訊
Judge judge=new Judge(responds,papers,questions,students,stone.getExistOfQuestions());//建立判題集
judge.printOut();//輸出
}
}
//////////////////////////////// 分界線 ////////////////////////////////
class Question{//問題類(基本)
private int numOfQuestion;
private String content;
private String standardAnswer;
public Question() {
}
public Question(int numOfQuestion, String content, String standardAnswer) {
this.numOfQuestion = numOfQuestion;
this.content = content;
this.standardAnswer = standardAnswer;
}
public String getStandardAnswer() {
return standardAnswer;
}
public String getContent() {
return content;
}
public int getNumOfQuestion() {
return numOfQuestion;
}
}
class Student{//學生類(基本)
private String ID;
private String name;
public String getName() {
return name;
}
public String getID() {
return ID;
}
public Student(String ID, String name) {
this.ID = ID;
this.name = name;
}
public Student() {
}
}
class Paper{//試卷類(基本)
private int numOfPaper;
private ArrayList<Integer> numOfQuestion;
private ArrayList<Integer> scoreOfQuestion;
public ArrayList<Integer> getScoreOfQuestion() {
return scoreOfQuestion;
}
public ArrayList<Integer> getNumOfQuestion() {
return numOfQuestion;
}
public int getNumOfPaper() {
return numOfPaper;
}
public Paper(int numOfPaper, ArrayList<Integer> numOfQuestion, ArrayList<Integer> scoreOfQuestion) {
this.numOfPaper = numOfPaper;
this.numOfQuestion = numOfQuestion;
this.scoreOfQuestion = scoreOfQuestion;
}
public Paper() {
}
}
class Respond{//答卷類(基本)
private int numOfRespond;
private String ID;
private ArrayList<Integer> numOfQuestion;
private ArrayList<String> myRespond;
public ArrayList<String> getMyRespond() {
return myRespond;
}
public ArrayList<Integer> getNumOfQuestion() {
return numOfQuestion;
}
public String getID() {
return ID;
}
public int getNumOfRespond() {
return numOfRespond;
}
public Respond(int numOfRespond, String ID, ArrayList<Integer> numOfQuestion, ArrayList<String> myRespond) {
this.numOfRespond = numOfRespond;
this.ID = ID;
this.numOfQuestion = numOfQuestion;
this.myRespond = myRespond;
}
public Respond() {
}
}
class Stone{ //題庫類 用於對題目集進行操作
private ArrayList<Question> questions;
private ArrayList<Integer> deletes=new ArrayList<>();
private ArrayList<Boolean> existOfQuestions=new ArrayList<>();
public Stone(ArrayList<Question> questions, ArrayList<Integer> deletes, ArrayList<Boolean> existOfQuestions) {
this.questions = questions;
this.deletes = deletes;
this.existOfQuestions = existOfQuestions;
}
public Stone(ArrayList<Question> questions) {
this.questions = questions;
}
public Stone() {
}
public ArrayList<Boolean> getExistOfQuestions() {
return existOfQuestions;
}
public void sort(){//排序
int maxnum=0;
int num;
String content = null;
String standardAnswer = null;
for(int i=0;i<questions.size();i++){
if(questions.get(i).getNumOfQuestion()>maxnum){
maxnum=questions.get(i).getNumOfQuestion();
}
}
boolean[] judge=new boolean[maxnum];
for(int i=0;i<questions.size();i++){
judge[questions.get(i).getNumOfQuestion()-1]=true;
}
for(int i=0;i<maxnum;i++){
if(!judge[i]){
num = i;
questions.add(new Question(num, content, "notexist"));
}
}
for(int i = 0;i < questions.size()-1;i++){
for(int j = 0;j < questions.size() - i - 1;j++){
if(questions.get(j).getNumOfQuestion() > questions.get(j+1).getNumOfQuestion()){
Question temp = questions.get(j);
questions.set(j,questions.get(j+1));
questions.set(j+1,temp);
}
}
}
for(int i=0;i< judge.length;i++){
existOfQuestions.add(judge[i]);
}
}
public void delete(){
for (int i=0;i<deletes.size();i++){
existOfQuestions.set(deletes.get(i)-1,false);
}
}
}
class Judge{//判題類 用於對答卷進行批改並進行輸出
private ArrayList<Respond> responds=new ArrayList<>();
private ArrayList<Paper> papers=new ArrayList<>();
private ArrayList<Question> questions=new ArrayList<>();
private ArrayList<Student> students=new ArrayList<>();
private ArrayList<Boolean> existOfQuestions=new ArrayList<Boolean>();
public Judge(ArrayList<Respond> responds, ArrayList<Paper> papers, ArrayList<Question> questions, ArrayList<Student> students,ArrayList<Boolean> existOfQuestions) {
this.responds = responds;
this.papers = papers;
this.questions = questions;
this.students = students;
this.existOfQuestions = existOfQuestions;
}
public Judge() {
}
public ArrayList<Question> getQuestions() {
return questions;
}
public ArrayList<Paper> getPapers() {
return papers;
}
public ArrayList<Respond> getResponds() {
return responds;
}
public void printOut(){
for (int i=0;i<papers.size();i++){//對試卷進行遍歷
int score=0;
//試卷總分警示
for(int j=0;j<papers.get(i).getNumOfQuestion().size();j++){
score+=papers.get(i).getScoreOfQuestion().get(j);
}
if (score!=100){
System.out.printf("alert: full score of test paper%d is not 100 points\n",i+1);
}
}
for (int i=0;i<responds.size();i++){//對答卷進行遍歷
int existOfPaper=0;
for (int j=0;j<papers.size();j++) {
if (responds.get(i).getNumOfRespond() == papers.get(j).getNumOfPaper()) {
existOfPaper=1;
}
}
if (existOfPaper==0){
System.out.println("The test paper number does not exist");
continue;
}
int score=0;
//判斷各道題目並輸出原題內容和學生答案以及正誤 、輸出判卷結果
score=0;
int scores[]=new int[papers.get(responds.get(i).getNumOfRespond()-1).getScoreOfQuestion().size()];
for (int j=0;j<papers.get(responds.get(i).getNumOfRespond()-1).getNumOfQuestion().size();j++) {//輸出每題內容得分情況及判斷結果
if (j<responds.get(i).getMyRespond().size()&&responds.get(i).getMyRespond().get(j)!="notexist") {
if (papers.get(responds.get(i).getNumOfRespond() - 1).getNumOfQuestion().get(j) - 1 < questions.size()) {
if (!questions.get(papers.get(responds.get(i).getNumOfRespond() - 1).getNumOfQuestion().get(j) - 1).getStandardAnswer().equals("notexist")) {
if (existOfQuestions.get(papers.get(i).getNumOfQuestion().get(j)-1)) {
System.out.print(questions.get(papers.get(responds.get(i).getNumOfRespond() - 1).getNumOfQuestion().get(j) - 1).getContent());
System.out.print("~");
System.out.print(responds.get(i).getMyRespond().get(j));
System.out.print("~");
if (questions.get(papers.get(responds.get(i).getNumOfRespond() - 1).getNumOfQuestion().get(j) - 1).getStandardAnswer().equals(responds.get(i).getMyRespond().get(j))) {
scores[j] = papers.get(responds.get(i).getNumOfRespond() - 1).getScoreOfQuestion().get(j);
System.out.println("true");
score += scores[j];
} else {
scores[j] = 0;
System.out.println("false");
}
} else {
scores[j] = 0;
System.out.printf("the question %d invalid~0\n", j + 1);//刪除題目題號可能為題庫內題號或試卷內題號
}
} else {
scores[j] = 0;
System.out.println("non-existent question~0");
}
} else {
scores[j] = 0;
System.out.println("non-existent question~0");
}
}
else {
System.out.println("answer is null");
}
}
int existOfStudent=0;
for (int j=0;j<students.size();j++) {//輸出答題人
if (students.get(j).getID().equals(responds.get(i).getID())) {
System.out.print(students.get(j).getID() + " ");
System.out.print(students.get(j).getName() + ":");
existOfStudent=1;
break;
}
}
if (existOfStudent==1) {
for (int j = 0; j < papers.get(responds.get(i).getNumOfRespond() - 1).getNumOfQuestion().size(); j++) {
System.out.printf(" %d", scores[j]);
}
System.out.println("~" + score);
}
else{
System.out.println(responds.get(i).getID()+" not found");
}
//
}
}
}
class GatMassage { //輸入類用於獲取輸入資訊
Scanner input = new Scanner(System.in);
private ArrayList<String> N = new ArrayList<>();
private ArrayList<String> T = new ArrayList<>();
private ArrayList<String> X = new ArrayList<>();
private ArrayList<String> S = new ArrayList<>();
private ArrayList<String> D = new ArrayList<>();
private ArrayList<String> F = new ArrayList<>();
public GatMassage() {
}
public void getDate() {//輸入
while (true) {
String str = input.nextLine();
if (str.equals("end")||str.matches("#N:\\s*(\\d+)\\s*#Q:\\s*(.*?)\\s*#A:\\s*(.*?)\\s*")||str.matches("^#T:( )*\\d+( )*((\\d+(( )*)-(( )*)\\d+( )*)+)$")||str.matches("(\\s*#X:\\s*)([0-9]+\\s+[^- ]+-)*([0-9]+\\s+[^- ]+)\\s*")||str.matches("#S:( )*\\d+( )*\\d+\\s*(.*?)$")||str.matches("#D:\\s*N\\s*-\\s*\\d+( )*$")/**/){
if (str.contains("#N:")) {
N.add(str);
}
if (str.contains("#T:")) {
T.add(str);
}
if (str.contains("#X:")) {
X.add(str);
}
if (str.contains("#S:")) {
S.add(str);
}
if (str.contains("#D:")) {
D.add(str);
}
if (str.equals("end")) {
break;
}
}
else
F.add(str);
}
}
public ArrayList<Question> treatN() {//對題目進行處理
ArrayList<Question> questions = new ArrayList<>();
String content = null;
int num;
String answer = null;
for (int i = 0; i < N.size(); i++) {
String[] parts = N.get(i).split("#N:|#Q:|#A:");
num = Integer.parseInt(parts[1].trim());
content = parts[2].trim();
answer = parts[3].trim();
questions.add(new Question(num, content, answer));
}
return questions;
}
public ArrayList<Paper> treatT() {//對試卷進行處理
ArrayList<Paper> papers = new ArrayList<>();
int num;
int score;
for (int i = 0; i < T.size(); i++) {
String[] parts = T.get(i).split("#T:|\\s+|-");
ArrayList<Integer> nunOfQuestions = new ArrayList<>();
ArrayList<Integer> scoreOfQuestions = new ArrayList<>();
ArrayList<String> part =new ArrayList<>();
for (int j=0;j< parts.length;j++){
part.add(parts[j].trim());
}
if (part.get(1)==""){
part.remove(1);
}
for (int j = 0; j < part.size()-3; j = j + 2) {
num = Integer.parseInt(part.get(j+2));
score = Integer.parseInt(part.get(j+3));
nunOfQuestions.add(num);
scoreOfQuestions.add(score);
}
Paper paper = new Paper(Integer.parseInt(part.get(1)), nunOfQuestions, scoreOfQuestions);
papers.add(paper);
}
return papers;
}
public ArrayList<Student> treatX() {//對學生進行處理
ArrayList<Student> students = new ArrayList<>();
ArrayList<String> part =new ArrayList<>();
String ID;
String name;
for (int i = 0; i < X.size(); i++) {
String[] parts = X.get(i).split("#X:|\\s+|-");
for (int j=0;j< parts.length;j++){
part.add(parts[j].trim());
}
if (part.get(1)==""){
part.remove(1);
}
for (int j = 0; j + 2 < part.size(); j = j + 2) {
ID = part.get(j+1);
name = part.get(j+2);
Student student = new Student(ID, name);
students.add(student);
}
}
return students;
}
public ArrayList<Respond> treatS() {//對答卷進行處理
ArrayList<Respond> responds = new ArrayList<>();
int numOfRespond;
String ID;
ArrayList<Integer> numOfQuestions = new ArrayList<>();
ArrayList<String> myResponds = new ArrayList<>();
for (int i = 0; i < S.size(); i++) {
String[] parts = S.get(i).split("#S:|\\s+|-|#A:");
ArrayList<String> part=new ArrayList<>();
for (int j=0;j<parts.length;j++){
part.add(parts[j].trim());
}
part.add("");
if (part.get(1)==""){
part.remove(1);
}
numOfRespond = Integer.parseInt(part.get(1));
ID = part.get(2);
int flag=0;
for(int j=4;j+2 < part.size(); j++){
if(part.get(j)!=""&&part.get(j+1)!=""){
flag=1;
continue;
}
if(part.get(j)==""&&flag==0){
part.remove(j);
flag=1;
continue;
}
if (part.get(j)==""&&flag==1){
flag=0;
continue;
}
}
for (int j = 4; j+1 < part.size(); j = j + 3) {
numOfQuestions.add(Integer.parseInt(part.get(j)));
myResponds.add(part.get(j+1));
}
int max=0;
for (int j=0;j<numOfQuestions.size();j++){
if(max<numOfQuestions.get(j)){
max=numOfQuestions.get(j);
}
}
boolean[]judge=new boolean[max];
for (int j=0;j<numOfQuestions.size();j++){
judge[numOfQuestions.get(j)-1]=true;
}
for (int j=0;j<max;j++){
if(!judge[j]){
numOfQuestions.add(j+1);
myResponds.add("notexist");
}
}
for(int j=0;j< numOfQuestions.size();j++){//答卷內排序
for (int l=j;l<numOfQuestions.size();l++){
if(j==numOfQuestions.get(l)-1){
int tempNum=numOfQuestions.get(l);
numOfQuestions.set(l,numOfQuestions.get(j));
numOfQuestions.set(j,tempNum);
String tempStr= myResponds.get(l);
myResponds.set(l,myResponds.get(j));
myResponds.set(j,tempStr);
}
}
}
Respond respond = new Respond(numOfRespond, ID, numOfQuestions, myResponds);
responds.add(respond);
}
return responds;
}
public ArrayList<Integer> treatD() {//對刪除資訊進行處理
ArrayList<Integer> deletes = new ArrayList<>();
int num;
if (D.size() > 0) {
String[] parts = D.get(0).split("#D:N-|\\s+N-");
for (int j = 0; j + 1 < parts.length; j++) {
num = Integer.parseInt(parts[j + 1].trim());
deletes.add(num);
}
}
return deletes;
}
public void treaF(){//對錯誤資訊進行輸出
for (int i=0;i< F.size();i++){
System.out.println("wrong format:"+F.get(i));
}
}
}
反思
這一次的作業由於上次程式碼寫的著實是太過於差,這次程式碼對整體的題目邏輯進行了很大的修改。首先就是類的數量由基礎的三個增加到了八個。其次由於本題對於錯誤格式的要求引入了正規表示式。我認為這是本題的一大重點難點所在。本次程式碼由於新增了兩個輸入類別、判斷錯誤的輸入格式和多種錯誤情況。同時出現多種錯誤情況只會輸出一條,也就是說錯誤的判定具有優先順序。因此我在新增的判題類(Judge)中運用了多重分支語句的寫法,這也導致了程式碼深度的增加。同時由於判定的條件可能存在多種,又產生了不少“&&”導致程式碼的複雜度也在增加。
踩坑心得
第一次作業
1.1
未出現語法和邏輯上的大問題,反倒由於審題不夠仔細,未發現題目中說明會進行亂序輸入導致卡題
隨後在對所有樣例進行測試以找出錯誤原因時發現盲點,隨後加入對題號的判定和以題號為判定標準的排序方法
第二次作業
2.1
在輸入為兩張試卷時,由於大迴圈中以試卷的數量作為標準,同時對於試卷的get方法和答卷的get方法採取同一個數i,所以導致在答卷和試卷輸入數量不同時會出現陣列越界的情況。同時如果試卷和答卷的題目號也會出現匹配不上的情況
思考後決定對於get方法中的資料進行改變,不直接引用迴圈迭代數i而是再get試卷或答卷的順序號作為get函式中的資料。以此來解決匹配不上的情況。同時將答卷的數量作為迴圈的判斷標準,以解決陣列越界的問題。
2.2
由於我在之前寫題時預設題號為連續,所以當有缺失的題號時我的程式碼僅能實現對它們進行基於大小的排序,但當呼叫題號時由於列表大小是基於排序後的個數的,所以缺失題號後當呼叫大題號時就會出現陣列越界的問題
由於如果採用判斷的方法會對程式碼有較大的改動,因此我採用了加入缺失題號進入題目陣列的方法,同時也定義應該Boolean型別的列表,如果是缺失的題目時則為false。這樣既解決了陣列越界的問題,也不用回頭對程式碼進行大改。只需要在呼叫題號時多加一重判斷Boolean列表是否為true。
PS.(這是我非常滿意的一個解決方法,它甚至讓我在下一次題目集中能較為輕易的解決刪除問題)
第三次作業
3.1
又一次未審題清楚,未注意到還有錯誤格式的情況存在!!
但由於並非程式碼的邏輯錯誤,僅在getMessage類中加入正規表示式進行匹配,如果不匹配即儲存為錯誤格式資訊即解決(但由於正規表示式的規範問題導致問題並未完全解決,還存在誤判的情況,後續對這個問題仍進行了多次修改)
3.2
由於對試卷內迴圈的判斷標準採用的是試卷中存在的題目數量,所以如果要同時判斷幾個錯誤情況的出現會存在陣列越界問題,而且如果有缺失的答案也會忽視或誤判為其他情況
改變迴圈判斷標準為答卷題目數量,並在進行下一輪迴圈前進行判斷,如果試卷還存在題目則下次迴圈不再get答卷題目資訊以免越界。
3.3
答卷中順序號未考慮完備
對於答卷中題目按照答題的順序進行排序並且與題庫中的題目順序進行區分以免呼叫時誤操作(慘痛經歷)
改進建議
在程式碼的命名和註釋方面還需進行最佳化,目前時常會出現因為呼叫的層數過多導致呼叫混淆的情況出現
正則的使用不夠完善,在匹配的過程中還會出現很多錯誤,需要對正規表示式的運用進行深入的學習
對類的設計還比較初級,類間關係的運用還時常出現問題,需要改進
總結
程式碼的設計是一個很關鍵的步驟,當見到一道題目的第一步不應該是直接開碼而是對類進行設計,使得程式碼既要滿足單一職責原則,也要滿足開閉原則(否則現在欠的債後面都要還的QAQ)
透過第三次題目集學習到了許多之前不瞭解的正規表示式匹配格式,正規表示式是很強大的一個匹配工具,可以實現多種格式的匹配
審題審題審題,一定要仔細看完題目的所有要求,否則在後續修改設計的時候可能會需要對之前的設計進行很大的改動。