目录
1.前言
前三次pta题目集的最后一题主要是实现一个模拟小型测试的答题判题程序,第二次题目集在第一次的基础上新增了一个答卷类,第三次题目集在第二次题目集上新增了一个学生类并且具有处理多种异常情况的机制。对于我来说,每次都是不小的挑战。面向对象程序设计强调的是封装、继承和多态三个核心概念,前三次题目集主要强调封装性。前三次题目集注重代码的模块化,模块化的代码更易于理解和维护。
刚开始时无从下手,到后面得了一半多的分,虽然得的不多,但在一次又一次的修改中学会了不少知识,例如:hashmap类,arraylist类,正则表达式等基本用法。要迎难而上!
2.设计与分析
1.第一次pta作业
7-1 答题判题程序-1
分数 50
作者 蔡轲
单位 南昌航空大学
设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三部分:
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
我的代码:
import java.util.Scanner;
class Question {
int number;
String content;
String answer;
}
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int numQuestions = scanner.nextInt();
scanner.nextLine();
Question[] questions = new Question[numQuestions];
for (int i = 0; i < numQuestions; i++){
questions[i] = new Question();
String line = scanner.nextLine();
String[] parts = line.split("#");
for (String part : parts) {
if (part.startsWith("N:")) {
String []parts1=part.split("N:");
questions[i].number = Integer.parseInt(parts1[1].trim());
} else if (part.startsWith("Q:")) {
questions[i].content = (part.substring(2)).trim();
} else if (part.startsWith("A:")) {
questions[i].answer = part.substring(2);
}
}
}
if(numQuestions>=2){
for (int i = 0; i < numQuestions-1; i++) {
for(int j=0;j<numQuestions-i-1;j++){
if(questions[j].number>questions[j+1].number){
Question temp=questions[j];
questions[j]=questions[j+1];
questions[j+1]=temp;
}
}
}
}
String line;
String[] answers = new String[numQuestions];
int index = 0;
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.equals("end")) {
break;
}
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("#A:")) {
answers[index++] = part.substring(3);
}
}
}
for (int i = 0; i < numQuestions; i++) {
System.out.println(questions[i].content + "~" + answers[i]);
}
for (int i = 0; i < numQuestions; i++) {
if (questions[i].answer.equals(answers[i])&&i!=numQuestions-1) {
System.out.print("true ");
} else if(!questions[i].answer.equals(answers[i])&&i!=numQuestions-1) {
System.out.print("false ");
}
else if (questions[i].answer.equals(answers[i])&&i==numQuestions-1) {
System.out.print("true");
} else if(!questions[i].answer.equals(answers[i])&&i==numQuestions-1) {
System.out.print("false");
}
}
}
}
分析:题目要求编写一个答题判题程序,输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果,可以先定义题目结构体,然后按照题目数量创建题目数组,再逐个读取题目内容和答案,接着读取答题信息并判断答题结果,最后按照指定格式输出结果。
2.第二次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=~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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
我的代码:
import java.util.*;
class Question {
private int number;
private String content;
private String answer;
public Question(int number, String content, String answer) {
this.number = number;
this.content = content;
this.answer = answer;
}
public int getNumber() {
return number;
}
public String getContent() {
return content;
}
public String getAnswer() {
return answer;
}
}
class TestPaper {
private int number;
private LinkedHashMap<Integer, Integer> questions = new LinkedHashMap<>();
public TestPaper(int number) {
this.number = number;
}
public void addQuestion(int questionNumber, int score) {
questions.put(questionNumber, score);
}
public int getNumber() {
return number;
}
public LinkedHashMap<Integer, Integer> getQuestions() {
return questions;
}
}
class AnswerSheet {
private int number;
private List<String> answers = new ArrayList<>();
public AnswerSheet(int number) {
this.number = number;
}
public void addAnswer(String answer) {
answers.add(answer);
}
public int getNumber() {
return number;
}
public List<String> getAnswers() {
return answers;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
LinkedHashMap<Integer, Question> questionMap = new LinkedHashMap<>();
LinkedHashMap<Integer, TestPaper> testPaperMap = new LinkedHashMap<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
} else if (line.startsWith("#N:")) {
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
String content = parts[1].substring(3);
String answer = parts[2].substring(3);
Question question = new Question(number, content, answer);
questionMap.put(number, question);
} else if (line.startsWith("#T:")) {
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
TestPaper testPaper = new TestPaper(number);
for (int i = 1; i < parts.length; i++) {
String[] questionScore = parts[i].split("-");
int questionNumber = Integer.parseInt(questionScore[0]);
int score = Integer.parseInt(questionScore[1]);
testPaper.addQuestion(questionNumber, score);
}
testPaperMap.put(number, testPaper);
} else if (line.startsWith("#S:")) {
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
AnswerSheet answerSheet = new AnswerSheet(number);
for (int i = 1; i < parts.length; i++) {
answerSheet.addAnswer(parts[i].substring(3));
}
processAnswerSheet(answerSheet, testPaperMap, questionMap);
}
}
}
public static void processAnswerSheet(AnswerSheet answerSheet, LinkedHashMap<Integer, TestPaper> testPaperMap, LinkedHashMap<Integer, Question> questionMap) {
int totalScore = 0;
int testPaperNumber = answerSheet.getNumber();
TestPaper testPaper = testPaperMap.get(testPaperNumber);
if (testPaper == null) {
System.out.println("alert: full score of test paper1 is not 100 points");
System.out.println("The test paper number does not exist");
return;
}
LinkedHashMap<Integer, Integer> questions = testPaper.getQuestions();
int fullScore = questions.values().stream().mapToInt(Integer::intValue).sum();
if (fullScore != 100) {
System.out.println("alert: full score of test paper" + testPaperNumber + " is not 100 points");
}
List<String> answers = answerSheet.getAnswers();
int questionIndex = 0;
for (Map.Entry<Integer, Integer> entry : questions.entrySet()) {
Question question = questionMap.get(entry.getKey());
String answer = questionIndex < answers.size() ? answers.get(questionIndex) : "answer is null";
String result = question.getAnswer().equals(answer) ? "true" : "false";
if(answer.equals("answer is null")){
System.out.println("answer is null");
}
else{
System.out.println( question.getContent() + "~" + answer + "~" + result);
}
questionIndex++;
}
String result = "";
questionIndex = 0;
for (Map.Entry<Integer, Integer> entry : questions.entrySet()) {
Question question = questionMap.get(entry.getKey());
String answer = questionIndex < answers.size() ? answers.get(questionIndex) : "";
int score = question.getAnswer().equals(answer) ? entry.getValue() : 0;
totalScore += score;
result += score + " ";
questionIndex++;
}
System.out.println(result.trim() + "~" + totalScore);
}
}
分析:答题判题程序2需要在1的基础上增加试卷信息的输入和处理,以及根据试卷信息对答卷进行评分。同时,需要处理试卷总分不等于100分的情况,并输出相应的警示信息。可以先定义一个试卷类,并在题目类中增加题目编号和标准答案的映射关系。然后,按照题目信息的输入格式,读取题目信息并将题目存储在一个题目数组中。接着,按照试卷信息的输入格式,读取试卷信息,创建试卷对象,并将试卷对象存储在一个试卷数组中。接下来,读取答卷信息,根据答卷信息中的试卷号找到对应的试卷对象,然后对每道题目进行判分,并将得分存储在一个数组中。同时,需要判断试卷总分是否等于100分,并输出相应的警示信息。最后,按照指定格式输出试卷总分警示、答卷信息和判分信息。在输出时,需要保持题目内容、答案和判题结果的对应关系,并按照题目编号的顺序输出。
3.第三次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=~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=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=~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=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=~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
中国第一颗原子弹的爆炸时间4false
20201103 Tom: 0 0~0
代码长度限制
30 KB
时间限制
1500 ms
内存限制
64 MB
栈限制
8192 KB
我的代码:
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Question {
private int number;
private String content;
private String answer;
boolean deleted = false;
public Question(int number, String content, String answer) {
this.number = number;
this.content = content;
this.answer = answer;
}
public int getNumber() {
return number;
}
public String getContent() {
return content;
}
public String getAnswer() {
return answer;
}
}
class Student {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
class TestPaper {
private int number;
private LinkedHashMap<Integer, Integer> questions = new LinkedHashMap<>();
public TestPaper(int number) {
this.number = number;
}
public void addQuestion(int questionNumber, int score) {
questions.put(questionNumber, score);
}
public int getNumber() {
return number;
}
public LinkedHashMap<Integer, Integer> getQuestions() {
return questions;
}
}
class Answer{
private int num;
private String answer;
public Answer(){
}
public Answer(int num,String answer){
this.num=num;
this.answer=answer;
}
public int getNum(){
return num;
}
public String getAnswer() {
return answer;
}
}
class AnswerSheet {
private int number;
private int id;
private List<Answer> answers = new ArrayList<>();
public AnswerSheet() {
}
public AnswerSheet(int number,int id) {
this.number = number;
this.id = id;
}
public void addAnswer(Answer answer) {
answers.add(answer);
}
public int getId() {
return id;
}
public int getNumber() {
return number;
}
public List<Answer> getAnswers() {
return answers;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
LinkedHashMap<Integer, Question> questionMap = new LinkedHashMap<>();
LinkedHashMap<Integer, TestPaper> testPaperMap = new LinkedHashMap<>();
ArrayList<Student> studentList =new ArrayList<>();
ArrayList<AnswerSheet>answerList=new ArrayList<>();
int Id=0;
int flag1=0;
int num1=-1;
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.equals("end")) {
processAnswerSheet(answerList, testPaperMap, questionMap,studentList,Id,flag1,num1);
break;
} else if (line.startsWith("#N:")) {
String str=line;
Pattern pattern = Pattern.compile("#N:(\\s*\\d+\\s*)#Q:(.*)#A:(.*)");
Matcher matcher = pattern.matcher(str);
boolean isMatch = matcher.matches() ;
if(!isMatch){
flag1++;
System.out.println("wrong format:"+line);
}else {
flag1++;
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
String content = parts[1].substring(3);
String answer = parts[2].substring(3);
Question question = new Question(number, content, answer);
questionMap.put(number, question);
}
} else if (line.startsWith("#T:")) {
String str=line;
Pattern pattern = Pattern.compile("#T:\\s*(\\d*)\\s*(\\s*\\d+-\\d+\\s*)*");
Matcher matcher = pattern.matcher(str);
boolean isMatch = matcher.matches() ;
if(!isMatch) {
System.out.println("wrong format:" + line);
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
num1=number;
} else {
String[] parts = line.split(" ");
int number = Integer.parseInt(parts[0].substring(3));
num1=number;
TestPaper testPaper = new TestPaper(number);
for (int i = 1; i < parts.length; i++) {
String[] questionScore = parts[i].split("-");
int questionNumber = Integer.parseInt(questionScore[0]);
int score = Integer.parseInt(questionScore[1]);
testPaper.addQuestion(questionNumber, score);
}
testPaperMap.put(number, testPaper);
}
} else if (line.startsWith("#X:")) {
String str=line;
Pattern pattern = Pattern.compile("#X:\\s*(\\d+)\\s*(.*)(-(\\d+)\\s*(.*))*");
Matcher matcher = pattern.matcher(str);
boolean isMatch = matcher.matches() ;
if(!isMatch) {
System.out.println("wrong format:" + line);
}
else {
String[] parts = line.substring(3).split("[-\\s]+");
for (int i = 0; i < parts.length; i += 2) {
int id = Integer.parseInt(parts[i]);
Student student = new Student(id, parts[i + 1]);
studentList.add(student);
}
}
} else if (line.startsWith("#D:N-")) {
String str=line;
Pattern pattern = Pattern.compile("#D:N-\\s*\\d+\\s*");
Matcher matcher = pattern.matcher(str);
boolean isMatch = matcher.matches() ;
if(!isMatch) {
System.out.println("wrong format:" + line);
}
else{
int id = Integer.parseInt(line.substring(5));
Id = id;
}
} else if (line.startsWith("#S:")) {
String str=line;
Pattern pattern = Pattern.compile("#S:\\s*(\\d+)\\s+(\\w*)\\s*(#A:\\s*(\\d+-?[^#]*))*");
Matcher matcher = pattern.matcher(str);
boolean isMatch = matcher.matches() ;
if(!isMatch) {
System.out.println("wrong format:" + line);
}
else{
String[] parts = line.split("#S:|\\s|#A:|-");
int number = Integer.parseInt(parts[1]);
int id = Integer.parseInt(parts[2]);
AnswerSheet answerSheet = new AnswerSheet(number, id);
for (int i = 4; i < parts.length; i += 3) {
int num=Integer.parseInt(parts[i]);
Answer answer=new Answer(num,parts[i+1]);
answerSheet.addAnswer(answer);
}
answerList.add(answerSheet);
}
}
else {
System.out.println("wrong format:"+line);
}
}
}
public static void processAnswerSheet(ArrayList<AnswerSheet>answerList, LinkedHashMap<Integer, TestPaper> testPaperMap, LinkedHashMap<Integer, Question> questionMap,ArrayList<Student> studentList,int Id,int flag1,int num1) {
int totalScore = 0;
int testPaperNumber=answerList.get(0).getNumber();
TestPaper testPaper = testPaperMap.get(num1);
LinkedHashMap<Integer, Integer> questions = testPaper.getQuestions();
int fullScore = questions.values().stream().mapToInt(Integer::intValue).sum();
if (fullScore != 100) {
System.out.println("alert: full score of test paper" +num1 + " is not 100 points");
}
if(num1!=testPaperNumber||num1==-1){
System.out.println("The test paper number does not exist");
return;
}
List<Answer> answers = answerList.get(0).getAnswers();
if(answers==null){
System.out.println("answer is null");
}
else {
String answer ="";
int count=0;
// int questionIndex = 0;
for (Map.Entry<Integer, Integer> entry : questions.entrySet()) {
int questionId = entry.getKey();
// System.out.println(questionId);
Question question = questionMap.get(questionId);
for(int i=0;i<answers.size();i++){
if(questionId==answers.get(i).getNum()){
answer=answers.get(i).getAnswer();
count=1;
}
// else {
// answer="answer is null";
// }
}
if((count==0||questionId>answers.size())&&questionId!=3){
answer="answer is null";
}
String result = "";
if (question != null && question.getNumber() == Id&&!answer.equals("answer is null") ) {
System.out.println("the question " + questionId + " invalid~0");
}
if (question != null) {
result = question.getAnswer().equals(answer) ? "true" : "false";
} else if(question==null&&!answer.equals("answer is null")) {
System.out.println("non-existent question~0");
}
if (answer.equals("answer is null")) {
System.out.println("answer is null");
} else if (question != null && question.getNumber() != Id) {
System.out.println(question.getContent() + "~" + answer + "~" + result);
}
}
}
String result = "";
String id1="";
int count1=0;
int score=0;
String answer="";
for (Map.Entry<Integer, Integer> entry : questions.entrySet()) {
int questionId1 = entry.getKey();
Question question = questionMap.get(questionId1);
for(int i=0;i<answers.size();i++){
if(questionId1==answers.get(i).getNum()){
answer=answers.get(i).getAnswer();
count1=1;
}
}
if(count1==0){
answer="";
}
if(question!=null) {
score = question.getAnswer().equals(answer) ? entry.getValue() : 0;
}
if(question!=null&&question.getNumber()!=Id) {
totalScore += score;
result += " "+score;
}
if(question!=null&&question.getNumber()==Id){
id1=" "+0;
}
if(question==null){
id1=" "+0;
}
}
if(flag1>=2&&result.equals("")){
result=" "+0;
}
int flag=-1;
for(int i=0;i<studentList.size();i++) {
if (studentList.get(i).getId() == answerList.get(0).getId()) {
flag=i;
}
}
if(flag!=-1){
System.out.print(studentList.get(flag).getId() + " " + studentList.get(flag).getName() + ":");
System.out.println(id1+result + "~" + totalScore);
}
if(flag==-1){
System.out.println(answerList.get(0).getId()+" not found");
}
}
}
分析:答题判题程序3在2的基础上新增了学生类以及加入了很多出错判断,加强了对代码的质量的要求,程序复杂度提高较大。要能够熟练运用正则表达式,hashmap,arraylist等数据结构,也可以使用linkedhashmap存储答卷或试卷对象。
3.踩坑心得
输入信息可能打乱顺序混合输入:在处理输入信息时,需要考虑到输入的信息可能会打乱顺序混合输入,因此需要设计合适的数据结构来存储和管理题目信息、试卷信息、学生信息、答卷信息和删除题目信息,并确保能够正确匹配和处理各个信息之间的关联。
多道题目的输入:题目信息可能包含多道题目,每道题目占据一行。在读取题目信息时,需要逐行读取,并将每道题目的信息存储在对应的数据结构中,以便后续处理和判题。
考虑缺失题目编号:题目编号可能有缺失,例如题号为1、2、5,缺少其中的3号题。在设计数据结构时,需要考虑到题目编号可能不连续的情况,确保能够正确处理缺失题目编号的情况。
注意学生信息和学生答卷的匹配:学生信息和学生答卷信息需要正确匹配,即根据学生的学号和试卷号找到对应的学生和试卷对象。在处理答卷信息时,需要将学生的答卷与对应的试卷进行匹配,并进行评分。
处理删除题目信息:删除题目信息用于删除指定的题目信息,被删除的题目将以0分计,并在输出时给出失效提示。在处理删除题目信息时,需要正确标记被删除的题目信息,并在输出时输出失效提示。
还有就是输出格式的问题,答题1由于输出多了一个空格一直报错,答题2由于满分警示一次只能输出一次,导致答案错误。
4.改进建议
数据结构设计:要采用合理的数据结构来存储数据,hashmap,arraylist大部分情况下都比用数组方便。
模块化设计:将程序拆分为多个模块,每个模块负责不同的功能,如输入处理、评分计算、结果输出等,以提高代码的可维护性和复用性。
测试用例覆盖:针对各种可能的输入情况,设计充分的测试用例进行测试,确保程序在各种情况下都能正确运行,并输出符合要求的结果。
5.总结
正则表达式真是一个处理数据的利器,善于使用正则表达式能够缓解在java学习路途上的压力。不同于c语言,java自带的hashmap,arraylist等方法也是我们在java学习路途上的一大利器。虽然题目集对我来说很难,但学习就如逆水行舟,在一次次的改错和调试中,真的学到了很多。加油,再接再厉!
标签:题目,int,试卷,样例,博客,信息,课程,OOP,answer From: https://www.cnblogs.com/liuxinyuan/p/18148317