前言:
在這個學期第一次學習Java,瞭解到這是一個適用範圍極大的語言,雖然相比於c/c++效率較低,但是更加的方便、簡單。經過這三次的PTA作業,使我受益匪淺,這三次作業相比於之前的作業,程式碼量和難度有巨大提升。
每次的PTA作業都有4到5道題,除了最後一道題,其他的題都相對簡單,可以幫助我們學習和複習知識點和語法。在第一次作業學習的類與物件的使用,在第二次作業學習了介面和抽象類,在第三次作業學習了日期類的使用。每次P他的最後一道題都是一個巨大的挑戰,它包含了各種知識點,需要一邊學習,一邊設計,一邊實現。
PTA第一次作業的最後一題
7-5 答題判題程式-1 分數 74 困難 作者 蔡軻 單位 南昌航空大學 設計實現答題程式,模擬一個小型的測試,要求輸入題目資訊和答題資訊,根據輸入題目資訊中的標準答案判斷答題的結果。
輸入格式:
程式輸入資訊分三部分:
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的題目的答案
78是題號為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
設計建議:
以下是針對以上題目要求的設計建議,其中的屬性、方法為最小集,實現程式碼中可根據情況新增所需的內容:
題目類(用於封裝單個題目的資訊):
屬性:題目編號、題目內容、標準答案-standardAnswer
方法:資料讀寫set\get方法、
判題方法(答案-answer):判斷答案-answer是否符合標準答案-standardAnswer
試卷類(用於封裝整套題目的資訊)
屬性:題目列表(題目類的物件集合)、題目數量
方法:判題方法(題號-num、答案-answer):判斷答案-answer是否符合對應題號的題目標準答案-standardAnswer
儲存題目(題號-num、題目-question):將題目儲存到題目列表中,儲存位置與num要能對應
答卷類(用於封裝答題資訊)
屬性:試卷(試卷類的物件)、答案列表(儲存每一題的答案)、判題列表(儲存每一題的判題結果true/false)
方法:判題方法(題號-num):判斷答案列表中第num題的結果是否符合試卷中對應題號的題目標準答案
輸出方法(題號-num):按照題目的格式要求,輸出題號為num的題目的內容和答題結果。
儲存一個答案(題號-num,答案-answer):儲存題號為num的題目的答題結果answer。
程式碼長度限制
16 KB
時間限制
400 ms
記憶體限制
64 MB
棧限制
8192 KB
這是第一次PTA作業的最後一題,相比較後兩次來說是最簡單的,類的設計簡單明確,也是我唯一一次滿分的。
原始碼
點選檢視程式碼
import java.util.*;
import java.util.Scanner;
import java.util.Map;
class Question {
private int num;
private String content;
private String standardAnswer;
public Question(int num, String content, String standardAnswer) {
this.num = num;
this.content = content;
this.standardAnswer = standardAnswer;
}
public int getNum() {
return num;
}
public String getContent() {
return content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public boolean judge(String answer) {
// return this.standardAnswer.trim().equalsIgnoreCase(answer.trim());
return this.standardAnswer.equals(answer);
}
}
class ExamPaper {
private Map<Integer, Question> questions = new TreeMap<>();
public void addQuestion(Question question) {
questions.put(question.getNum(), question);
}
public Collection<Question> getQuestions() {
return questions.values();
}
public Question getQuestion(int num) {
return questions.get(num);
}
}
class ExamAnswer {
private ExamPaper examPaper;
private Map<Integer, String> answers = new LinkedHashMap<>();
public ExamAnswer(ExamPaper examPaper) {
this.examPaper = examPaper;
}
public void addAnswer(int questionNumber, String answer) {
answers.put(questionNumber, answer);
}
public void printlast() {
// Question question;
int flag=0;
int ab=0;
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
//String answer = answers.get(question.getNum());
Map<Integer, Boolean> judges = new HashMap<>();
for ( Question question : examPaper.getQuestions()) {
flag++;
String answer = answers.get(question.getNum());
System.out.println(question.getContent() + "~" + answer);
judges.put(question.getNum(), question.judge(answer));
}
for (Map.Entry<Integer, Boolean> entry :judges.entrySet()) {
if(ab==0){
System.out.print( entry.getValue());
}
else{
System.out.print( " "+entry.getValue());
}
ab++;
}
}}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i;
int questionsum = Integer.parseInt(scanner.nextLine());
// Integer questionsum=scanner.next();
ExamPaper examPaper = new ExamPaper();
for (i=0;i<questionsum; i++) {
String[] question1 = scanner.nextLine().trim().split(" #");
int num = Integer.parseInt(question1[0].split(":")[1].trim());
String content = question1[1].split(":")[1].trim();
String standardAnswer = question1[2].split(":")[1].trim();
Question question = new Question(num,content,standardAnswer);
examPaper.addQuestion(question);
}
ExamAnswer examAnswer = new ExamAnswer(examPaper);
String[] answers = scanner.nextLine().trim().substring(3).split(" #A:");
for (i = 0; i < answers.length; i++) {
examAnswer.addAnswer(i+1, answers[i].trim());
}
examAnswer.printlast();
}
}
類圖
改進建議
因為這道題相對簡單,因此功能實現比較完整,但還有一定的缺陷,就是沒有完全實現單一變數職責,沒有將字串解析單獨製作成一個類,而是直接放在主類中,後續可以改進。
PTA第二次作業最後一題
7-2 答題判題程式-2 分數 54 作者 蔡軻 單位 南昌航空大學 設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-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=5true
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=5false
2+2=22false
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=5false
2+2=22false
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=5false
2+2=4true
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=5false
1+1=22false
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=5true
2+2=22false
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=5true
2+2=22false
70 0~70
3+2=5true
2+2=4true
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=5true
2+2=22false
7 0~7
3+2=5true
2+2=4true
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=5true
2+2=22false
7 0~7
2+2=5false
1+1=4false
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
程式碼長度限制
16 KB
時間限制
400 ms
記憶體限制
64 MB
棧限制
原始碼
點選檢視程式碼
import java.util.*;
import java.util.Scanner;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question {
private int num;
private String content;
private String standardAnswer;
public Question(int num, String content, String standardAnswer) {
this.num = num;
this.content = content;
this. standardAnswer = standardAnswer;
}
public int getNum() {
return num;
}
public String getContent() {
return content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public boolean judge(String answer) {
// return this.standardAnswer.trim().equalsIgnoreCase(answer.trim());
return this.standardAnswer.equals(answer);
}
}
class ExamPaper {
private int num;
private Map<Integer, Integer> questionscore = new LinkedHashMap<>();
// private static Map<Integer,Question> questions=new HashMap<>();
public void addQuestion(int questionid ,int score) {
questionscore.put(questionid, score);
}
public ExamPaper(int num)
{
this.num=num;
}
public Map<Integer,Integer> getQuestions() {
return questionscore;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getTotalScore() {
int total = 0;
for (int score : questionscore.values()) {
total += score;
}
return total;
}
}
class ExamAnswer {
private ExamPaper examPaper;
private static Map<Integer, ExamPaper> testPapers = new HashMap<>();
private List<String> answers = new ArrayList<>();
private int paperid;
// private static List<ExamAnswer> examAnswer = new ArrayList<>();
public ExamAnswer(int paperid,List<String> answers) {
this.paperid=paperid;
this.answers=answers;
}
public int getPaperId() {
return paperid;
}
public List<String> getAnswers(){
return answers;
}
public ExamAnswer(ExamPaper examPaper) {
this.examPaper = examPaper;
}
// public void addAnswer(int questionNumber, String answer) {
// answers.put(questionNumber, answer);
// }
// public void printlast() {
// // Question question;
// int flag=0;
// int ab=0;
// StringBuilder sb = new StringBuilder();
// boolean isFirst = true;
// //String answer = answers.get(question.getNum());
// Map<Integer, Boolean> judges = new HashMap<>();
// for ( Question question : examPaper.getQuestions()) {
//
// flag++;
// String answer = answers.get(question.getNum());
// System.out.println(question.getContent() + "~" + answer);
// judges.put(question.getNum(), question.judge(answer));
//
// }
// for (Map.Entry<Integer, Boolean> entry :judges.entrySet()) {
//
// if(ab==0){
// System.out.print( entry.getValue());
// }
//
// else{
// System.out.print( " "+entry.getValue());
// }
// ab++;
//
//}
}
public class Main {
private static Map<Integer, Question> questions = new HashMap<>();
private static Map<Integer, ExamPaper> examPapers = new HashMap<>();
private static List<ExamAnswer> ExamAnswers = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.+) #A:(.+)");
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if ("end".equals(line)) {
break;
}
if (line.startsWith("#N:")) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
String content = matcher.group(2).trim();
String answer = matcher.group(3).trim();
Question ques=new Question(id,content,answer);
questions.put(id,ques );
}
} else if (line.startsWith("#T:")) {
String[] parts = line.split(" ");
int paperId = Integer.parseInt(parts[0].substring(3));
ExamPaper examPaper = new ExamPaper(paperId);
for (int i = 1; i < parts.length; i++) {
String[] questionInfo = parts[i].split("-");
int questionId = Integer.parseInt(questionInfo[0]);
int score = Integer.parseInt(questionInfo[1]);
examPaper.addQuestion(questionId, score);
}
examPapers.put(paperId, examPaper);
} else if (line.startsWith("#S:")) {
String[] parts = line.split(" ");
int paperId = Integer.parseInt(parts[0].substring(3));
List<String> answers = new ArrayList<>();
for (int i = 1; i < parts.length; i++) {
String answer = parts[i].substring(3).trim();
answers.add(answer);
}
ExamAnswers.add(new ExamAnswer(paperId, answers));
}
}
for (ExamAnswer examAnswer : ExamAnswers) {
ExamPaper examPaper = examPapers.get(examAnswer.getPaperId());
if (examPaper == null || examPaper.getTotalScore() != 100) {
System.out.println("alert: full score of test paper" + examAnswer.getPaperId() + " is not 100 points");
}
}
for(ExamAnswer examAnswer: ExamAnswers) {
ExamPaper examPaper= examPapers.get(examAnswer.getPaperId());
int total=0;
int i=0;
List<String> userAnswers = examAnswer.getAnswers();
for (Map.Entry<Integer, Integer> entry : examPaper.getQuestions().entrySet()) {
Question question = questions.get(entry.getKey());
if (question != null) {
String userAnswer;
int flag1=0;
if (i < userAnswers.size()) {
userAnswer = userAnswers.get(i);
} else {
userAnswer = "answer is null";
flag1=1;
}
boolean flag = question.judge(userAnswer);
if (flag) {
total += entry.getValue();
System.out.println(question.getContent() + "~" + userAnswer + "~true");
} else {
if(flag1==0) {
System.out.println(question.getContent() + "~" + userAnswer + "~false");
}
if(flag1==1) {
System.out.println( userAnswer );
}
}
} else {
System.out.println("answer is null");
}
i++;
}
StringBuilder prints = new StringBuilder();
int last = 0;
for (Integer score : examPaper.getQuestions().values()) {
if (last < userAnswers.size()) {
ArrayList<Integer> questionKeys = new ArrayList<>(examPaper.getQuestions().keySet());
int last1 = last;
Question question = questions.get(questionKeys.get(last1));
if (question != null && question.judge(userAnswers.get(last))) {
prints.append(score).append(" ");
} else {
prints.append("0 ");
}
} else {
prints.append("0 ");
}
last++;
}
if (prints.length() > 0) {
prints.deleteCharAt(prints.length() - 1);}
prints.append("~").append(total);
System.out.println(prints.toString());
}
}
}
類圖
踩坑心得
因為這次的程式碼難度有所提升,因此沒有滿分,但是還是得了大部分分,踩了一部分坑,除錯了很久
1.沒有想清楚類之間的關係,因此設計的時候很亂。
2.沒有完全符合單一變數職責。
3.輸出資訊的順序不對,導致輸出混亂。
4.沒有提前畫類圖構思,而是寫一步想一步。
5.沒有加入新的類,而是對類進行增加,不符合開閉原則
改進建議
1.應增加幾個類,實現不同的職責
2.在設計類的時候應提前做類圖,有設計的方向
3.在設計類的時候先明白麵向的物件的目的,瞭解類之間的關係
4.此程式碼沒解決輸入錯誤的問題,因此顯示非零返回,應判斷資料是否為null,是否越界
PTA第三次作業最後一題
7-3 答題判題程式-3
分數 80
作者 蔡軻
單位 南昌航空大學
設計實現答題程式,模擬一個小型的測試,以下粗體字顯示的是在答題判題程式-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=5false
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=5true
4+6=22false.
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=5false
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=2true
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=5false
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=5false
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=5false
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=5false
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=5false
中國第一顆原子彈的爆炸時間4false
20201103 Tom: 0 0~0
程式碼長度限制
30 KB
時間限制
1500 ms
記憶體限制
64 MB
棧限制
8192 KB
原始碼
點選檢視程式碼
import java.util.*;
import java.util.Scanner;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question {
private int num;
private String content;
private String standardAnswer;
public Question(int num, String content, String standardAnswer) {
this.num = num;
this.content = content;
this. standardAnswer = standardAnswer;
}
public int getNum() {
return num;
}
public String getContent() {
return content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public boolean judge(String answer) {
// return this.standardAnswer.trim().equalsIgnoreCase(answer.trim());
return this.standardAnswer.equals(answer);
}
}
class ExamPaper {
private int num;
private Map<Integer, Integer> questionscore = new LinkedHashMap<>();
// private static Map<Integer,Question> questions=new HashMap<>();
public void addQuestion(int questionid ,int score) {
questionscore.put(questionid, score);
}
public ExamPaper(int num)
{
this.num=num;
}
public Map<Integer,Integer> getQuestions() {
return questionscore;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getTotalScore() {
int total = 0;
for (int score : questionscore.values()) {
total += score;
}
return total;
}
}
class ExamAnswer {
private int paperId;
private List<String> answers = new ArrayList<>();
private String studentId;
private int questionOrder;
public ExamAnswer(int paperId, String studentId, int questionOrder, List<String> answers) {
this.paperId = paperId;
this.answers = answers;
this.questionOrder = questionOrder;
this.studentId = studentId;
}
public int getQuestionOrder() {
return questionOrder;
}
public int getPaperId() {
return paperId;
}
public List<String> getAnswers() {
return answers;
}
public String getStudentId() {
return studentId;
}
}
class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
class DeleteQuestion {
private static List<DeleteQuestion> deletedQuestions = new ArrayList<>();
private int questionId;
public DeleteQuestion(int questionId) {
this.questionId = questionId;
}
public static void updata(int questionId, ExamPaper examPaper) {
// examPaper.getQuestions().remove(questionId);
examPaper.getQuestions().put(questionId, 0);
}
public int getQuestionId() {
return questionId;
}
public static void deleteQuestion(int questionId) {
deletedQuestions.add(new DeleteQuestion(questionId));
}
public static boolean isQuestionDeleted(int questionId) {
for (DeleteQuestion dq : deletedQuestions) {
if (dq.getQuestionId() == questionId) {
return true;
}
}
return false;
}
public static void printDeletedQuestion(Question question) {
System.out.println("the question " + question.getNum() + " invalid~0");
}
}
class AnswerWithOrder {
int questionOrder;
String answer;
public AnswerWithOrder(int questionOrder, String answer) {
this.questionOrder = questionOrder;
this.answer = answer;
}
public int getQuestionOrder() {
return questionOrder;
}
public String getAnswer() {
return answer; }
}
class Regex{
//#N
public static boolean matchN(String line) {
String regex = "#N:(\\d{1}) #Q:(\\d{1})\\+(\\d{1})= #A:(\\d{1})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
//#T
public static boolean matchT(String line) {
// String regex = "#T:(\\d{1}) (\\d{1})-(.*)$";
String regex = "^#T:\\d+( \\d+-\\d+)*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
return matcher.matches(); }
//#S:
public static boolean matchS(String line) {
String regex = "^#S:\\d+\\s+\\d{8}(\\s+#A:\\d+-\\d+)*$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
//#X:
public static boolean matchX(String line) {
//String regex = "^#X:(\\d+\\s+[a-zA-Z]+-)";
String regex = "(\\s*#X:\\s*){1}([0-9]+\\s+[^- ]+-){0,}([0-9]+\\s+[^- ]+){1}\\s*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
//#D
public static boolean matchD(String line) {
String regex = "^#D:N-\\d+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
}
public class Main {
private static Map<Integer, Question> questions = new HashMap<>();
private static Map<Integer, ExamPaper> examPapers = new HashMap<>();
private static List<ExamAnswer> ExamAnswers = new ArrayList<>();
private static List<Student> students = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.+) #A:(.+)");
// Pattern pattern =
int studentflag1=0;
int studentflag2=0;
int studentflag3=0;
int paperId1=0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if ("end".equals(line)) {
break;
}
if (line.startsWith("#N:")) {
if(!Regex.matchN(line)){
System.out.println("wrong format:" + line);
continue;
}
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
String content = matcher.group(2).trim();
String answer = matcher.group(3).trim();
Question ques = new Question(id, content, answer);
questions.put(id, ques);
}
}
else if(Regex.matchT(line)){
String[] parts = line.split(" ");
int paperId = Integer.parseInt(parts[0].substring(3));
paperId1=paperId;
ExamPaper examPaper = new ExamPaper(paperId);
for (int i = 1; i < parts.length; i++) {
String[] questionInfo = parts[i].split("-");
int questionId = Integer.parseInt(questionInfo[0]);
int score = Integer.parseInt(questionInfo[1]);
examPaper.addQuestion(questionId, score);
}
examPapers.put(paperId, examPaper);}
else if(Regex.matchX(line)){
studentflag1=1;
String[] parts = line.substring(3).split("-");
// List<Student> students = new ArrayList<>();
for (String part : parts) {
String[] info = part.trim().split(" ");
if (info.length == 2) {
String id = info[0];
String name = info[1];
students.add(new Student(id, name));
}
}}
else if(Regex.matchS(line)){
String[] parts = line.split(" ");
int paperId = Integer.parseInt(parts[0].substring(3));
String studentId = parts[1];
int questionOrder = 0;
List<String> answers = new ArrayList<>();
List<AnswerWithOrder> answersWithOrder=new ArrayList<>();
for (int i = 2; i < parts.length; i++) {
String[] answerParts = parts[i].split("-");
questionOrder = Integer.parseInt(answerParts[0].substring(3));
// String answerd = answerParts[1];
String answer = answerParts[1];
// answers.add(answerd);
answersWithOrder.add(new AnswerWithOrder(questionOrder,answer));
}
answersWithOrder.sort(Comparator.comparingInt(AnswerWithOrder::getQuestionOrder));
for (AnswerWithOrder lastlist1 : answersWithOrder) {
answers.add(lastlist1.getAnswer());
}
ExamAnswers.add(new ExamAnswer(paperId, studentId, questionOrder, answers));
}
else if(Regex.matchD(line)){
int questionId = Integer.parseInt(line.substring(5));
DeleteQuestion.deleteQuestion(questionId);
}
else {
System.out.println("Wrong Format:" + line);
}
}
//System.out.println("a");//測試
for (ExamAnswer examAnswer : ExamAnswers) {
// for(Map<Integer,ExamPaper> exampaper :examPapers){
ExamPaper examPaper = examPapers.get(examAnswer.getPaperId());
if (examPaper== null || examPaper.getTotalScore() != 100) {
// if ( examPaper!= null &&examPaper.getTotalScore() != 100) {
System.out.println("alert: full score of test paper" + paperId1+ " is not 100 points");
// }
}
}
for(ExamAnswer examAnswer: ExamAnswers) {
ExamPaper examPaper= examPapers.get(examAnswer.getPaperId());
List<String> userAnswers = examAnswer.getAnswers();
int total=0;
int i=0;
if(examPaper ==null) {
System.out.println("The test paper number does not exist");
}
else{ for (Map.Entry<Integer, Integer> entry : examPaper.getQuestions().entrySet()) {
//entry是exampaper的問題分數map對映 examPaper.getQuestions().values()
//entry.getKey()是#T的試卷號/問題id
// System.out.println(entry.getKey());//用於測試
Question question = questions.get(entry.getKey());
// if (question == null) {
// System.out.println("non-existent question~" +0) ;//userAnswers.get(i));
// i++;
// continue;
// }
String userAnswer;
int flag1=0;
if (i < userAnswers.size()) {
userAnswer = userAnswers.get(i);
} else {
total += 0;
System.out.println("answer is null");
i++;
continue;
}
// System.out.println(question);//用於測試
// // 刪除
int deleteflag=0;
if (DeleteQuestion.isQuestionDeleted(entry.getKey())) {
DeleteQuestion.printDeletedQuestion(question);
DeleteQuestion.updata(entry.getKey(),examPaper);
// if (question == null) {
// System.out.println("non-existent question~" +0) ;//userAnswers.get(i));
// i++;
// continue;
// }
deleteflag=1;
i++;
continue;
}
if (question == null) {
System.out.println("non-existent question~" +0) ;//userAnswers.get(i));
i++;
continue;
}
if (question != null) {//1
boolean flag = question.judge(userAnswer);
if (flag) {
if(deleteflag==0){total += entry.getValue();}
if(deleteflag==0){total += 0;}
System.out.println(question.getContent() + "~" + userAnswer + "~true");
} else {
System.out.println(question.getContent() + "~" + userAnswer + "~false");
}
}//1
}
for(Student student:students){
if(student.getId().equals(examAnswer.getStudentId())){
System.out.print(student.getId()+" "+student.getName()+": ");
studentflag3=1;
}
if(studentflag3==0) {
System.out.print(examAnswer.getStudentId()+" not found");
studentflag2=1;
}
}
StringBuilder prints = new StringBuilder();
int last = 0;
if(!(studentflag1==1&&studentflag2==1)){
for (Integer score : examPaper.getQuestions().values()) {
if (last < userAnswers.size()) {
ArrayList<Integer> questionKeys = new ArrayList<>(examPaper.getQuestions().keySet());
int last1 = last;
Question question = questions.get(questionKeys.get(last1));
if (question != null && question.judge(userAnswers.get(last))) {
prints.append(score).append(" ");
} else {
prints.append("0 ");
}
} else {
prints.append("0 ");
}
last++;
}
if (prints.length() > 0) {
prints.deleteCharAt(prints.length() - 1);}
prints.append("~").append(total);
System.out.println(prints.toString());
}
}
}
}
}
類圖
這次是難度最大的一次,我只得了一半的分數
踩坑心得
1.還是那個問題,沒能完全清楚類之間的關係,做出來的類可以說是毫無聯絡。
2.雖然新增很很多類,但是無法完全的單一職責。
3.很多的因為輸出null,陣列越界沒有解決。
4.正規表示式有點小問題。
5.在上一次程式碼的基礎上可以說是大改,而不是基於它來改。
6.類之間引用的時候沒有理清關係而導致引用錯誤。
7.沒有邊寫邊註釋,在下一次看的時候要重新思考。
8.在主類中沒有設定方法,而是直接裸出程式碼,導致程式碼很亂,沒有規則性。
改進建議
1.最基本的問題,邊寫程式碼邊註釋,方便自己也方便他人。
2.在寫程式碼之前理清物件導向的方向的目標,做出類圖。
3.在報錯的時候理性分析,之前因為一個很簡單的非零返回卡了三天。
4.多學習和使用正規表示式,很方便但容易錯,很多的測試點因為正規表示式而沒過。
5.再增加幾個類,實現單一職責。
6.沒實現亂序輸入。
總結
經過這三次的PTA作業,讓我學到很多東西,收穫了很多道理。
1.對Java的學習更加深入,對語法更加熟悉。
2.在這次的PTA作業中,遇到了很多的問題,這些問題一眼來很難解決,但是必須要解決;要培養自己解決問題的能力,無論遇到什麼困難都要自己一點一點的克服。
3.在遇到問題時要提前解決,不能拖時間,雖然這次我很早就做PTA了還是沒有做到滿意的成都,可見要是拖到最後的後果。
4.要獨立自主學習,提前在網上學習要用到的的知識點,才能順利完成自己的問題。
5.在寫程式碼之前要完成類圖,做出自己的設計,不能邊做邊設計,否則可能做到一半就和麵向的物件要求不符合。 <6>6.思考問題要全面,不能思考眼前的問題,要思考大局。
7.在學習態度上沒有完全端正,很多的時候做好目標自己就怠惰了,在今後要解決這種問題。
8.在對映方面的學習程度要加深,在寫程式碼的時候我深深瞭解到它的重要性,它能實現很多的需求。
在這輪的PTA作業中,我受益匪淺,在物件導向的方向上學習了很多,瞭解了類與物件,各種的原則,在下次的PTA作業中會繼續學習繼承與多型,希望在今後的學習中能掌握和使用繼承和多型做程式的設計。