nchu-oop训练集1~3总结

--Leslie-- / 2024-04-21 / 原文

一、前言
Java学习已经有一个多月了,虽然还是有些困难,但已不像初学C语言时那般吃力,Java是一门非常强大且有趣的编程语言。我喜欢Java的面向对象的特性,它让我可以更好地组织和管理我的代码。另外,Java的跨平台性也让我感到很方便,我可以在不同的操作系统上运行我的程序。
这三次题目集对我来说还是有些难度的,题量比较大,题目也很难,学习Java可能会有一些挑战,比如理解一些概念和语法规则,但是通过不断练习和实践,我相信我会越来越熟练。

二、设计与分析
第一次训练集
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

输入样例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.*;
import java.util.Scanner;

public class Main{
public static void main(String[] args) {  
        Scanner input = new Scanner(System.in);  
        int count =input.nextInt();
        input.nextLine();
        Question[] question = new Question[count]; 
        for(int i=0;i<count;i++)
        {
            String q = input.nextLine();
            int index1 = q.indexOf("#N:");
            int index2 = q.indexOf("#Q:");
            int index3 = q.indexOf("#A:");
            String num = q.substring(index1+3,index2).trim();
            int number = Integer.parseInt(num);
            String content = q.substring(index2+3,index3).trim();
            String standardAnswer = q.substring(index3+3,q.length()).trim();
            question[number-1] = new Question(number,content,standardAnswer);
        }
    
        TestPaper testPaper = new TestPaper(question);
        String an=input.nextLine();
        int index[]=new int[count];
        int n=0;
        String[] answers = new String[count];
        for(int i=0;i<count;i++)
        {
            index[i]=an.indexOf("#A:",n);
            n=index[i] + 1;
        }
        for(int i=0;i<count;i++)
        {
            if(i==count-1)
                answers[i] = an.substring(index[i]+3,an.length()).trim();
            else 
                answers[i] = an.substring(index[i]+3,index[i+1]).trim();
        }
        Answer answer = new Answer(count,testPaper,answers);
        for(int i=0;i<count;i++)
            answer.check(i);
        for(int i=0;i<count;i++)
            System.out.println(question[i].getContent()+"~"+answers[i]);
        for(int i=0;i<count;i++){
            if(i!=count-1)
                System.out.print(answer.getresults(i)+" ");
            else
                System.out.printf("%s",answer.getresults(i));
        }
    }
}
class Question {  
    private int number;  
    private String content;  
    private String standardAnswer;  
    public Question(){
        
    }
    public Question(int number, String content, String standardAnswer) {  
        this.number = number;  
        this.content = content;  
        this.standardAnswer = standardAnswer;  
    }  
  
    public int getNumber() {  
        return number;  
    }  
  
    public String getContent() {  
        return content;  
    }  
  
    public String getStandardAnswer() {  
        return standardAnswer;  
    }  
  
    public boolean isCorrectAnswer(String answer) {  
        return standardAnswer.equals(answer);
    }
}

class TestPaper {  
    private Question[] questions;
    TestPaper(Question[] questions)
    {
        this.questions = questions;
    }
    public boolean check(int id,String ans)
    {
        return questions[id].isCorrectAnswer(ans);
    }
    
}

class Answer {  
    private TestPaper testPaper;  
    private String[] answers;
    private boolean[] results; 
    public Answer(int num,TestPaper testPaper,String[] answers)
    {
        this.answers = new String[num];
        this.results = new boolean[num];
        this.testPaper = testPaper;
        this.answers=answers;
        
    }
    public void check(int id)
    {
        this.results[id] = testPaper.check(id,answers[id]);
    }
    public boolean getresults(int id)
    {
        return results[id];
    }
}

分析
代码中包括三个类:
Question类代表一个问题,包含问题编号、内容和标准答案。
TestPaper类包含问题数组,并提供方法来检查给定问题的答案是否正确。
Answer类接收试卷、用户提供的答案和答案检查结果,并提供方法来检查答案和获取结果。
在Main类中,程序读取输入来创建问题、创建试卷、读取答案、检查答案,最后打印结果。

整体而言,这个程序的功能是简单的试卷答题系统。

第二次训练集
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=22false.
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=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

代码如下

  
import java.util.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashMap;

public class Main{
public static void main(String[] args) {  
        Scanner input = new Scanner(System.in);
        LinkedHashMap question = new LinkedHashMap();
        LinkedHashMap testpaper = new LinkedHashMap();
        LinkedList ans = new LinkedList<>();
        while(true)
        {
            String newin = input.nextLine();
            //System.out.println(newin);
            if(newin.equals("end"))
            {
                break;
            }
            if(newin.startsWith("#N:"))
            {
                int index1 = newin.indexOf("#N:");
                int index2 = newin.indexOf("#Q:");
                int index3 = newin.indexOf("#A:");
                String num = newin.substring(index1+3,index2).trim();
                int number = Integer.parseInt(num);
                String content = newin.substring(index2+3,index3).trim();
                String standardAnswer = newin.substring(index3+3,newin.length()).trim();
                question.put(number,new Question(content,standardAnswer));
            }
            if(newin.startsWith("#T:"))
            {
                String regex = "#T:\\s*(\\d+)\\s*(.*)";
                Pattern pat = Pattern.compile(regex);
                Matcher mat = pat.matcher(newin);
                mat.find();
                int pid = Integer.parseInt(mat.group(1).trim());
                //System.out.printf("%d\n",pid);
                TestPaper paper = new TestPaper();
                Pattern pat1 = Pattern.compile("(\\d*)-(\\d*)");
                Matcher mat1 = pat1.matcher(newin);
                while(mat1.find())
                {
                    int qid=Integer.parseInt(mat1.group(1));
                    int score =Integer.parseInt(mat1.group(2));
                    paper.addQuestion(qid,score);
                    //System.out.printf("%d %d\n",qid,score);
                }
                testpaper.put(pid,paper);
            }
            if(newin.startsWith("#S:"))
            {
                String regex = "#S:\\s*(\\d*)\\s*(#A:(.*))*";
                Pattern pat2 = Pattern.compile(regex);
                Matcher mat2 = pat2.matcher(newin);
                mat2.find();
                int aid = Integer.parseInt(mat2.group(1).trim());
                
                //System.out.print(aid);
                Listanswers = null;
                int count=0;
                if(testpaper.containsKey(aid))
                {
                    int n = testpaper.get(aid).getnumber();
                    Pattern pat3 = Pattern.compile("#A:");
                    Matcher mat3 = pat3.matcher(newin);
                    while(mat3.find())
                    {
                        count++;
                    }
                        int index[]=new int[count];
                        for(int i=0;i();
                        for(int i=0;i questions = new LinkedHashMap();
    private int fullscore=0;
    TestPaper()
    {
        
    }
    public int getnumber()
    {
        return number;
    }
    public int getfullscore()
    {
        return fullscore;
    }
    public Map getquestions(){
        return Collections.unmodifiableMap(questions);
    }
    public void addQuestion(int qid, int score) {
            questions.put(qid, score);
            fullscore += score;
            number++;
    }
}

class Answer {  
    private int aid;
    private int count;
    private Listanswers = new ArrayList();
    private Listresults = new ArrayList();
    public Answer(List answers,int count,int aid)
    {
        this.answers=answers;
        this.count=count;
        this.aid=aid;
    }
    public int getid()
    {
        return aid;
    }
    public int getcount()
    {
        return count;
    }
    public List getanswers(){
        return answers;
    }
    public void setresults(boolean result){
        this.results.add(result);
    }
    public List getresults(){
        return results;
    }
}

分析
Question、TestPaper和Answer等类来表示问题、试卷和答案。主要逻辑在Main类中,负责处理输入和输出。代码可能存在一些问题,如输入解析、错误处理和逻辑错误。

第三次训练题
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 javax.swing.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.Comparator;
class Issue//题目类
{
    public int number;
    public String question;
    public String answer;//标准答案
    public Issue(int number, String question, String answer)
    {
        this.number = number;
        this.question = question;
        this.answer = answer;
    }

    public Issue()
    {
    }
    public Boolean check(String answer)
    {
        if(this.answer.equals(answer))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public String toString(String answer)
    {
        if(this.answer.equals(answer))
        {
            if(answer.equals("null"))
            {
                return this.question+"~"+""+"~true";
            }
            else
            {
                return this.question+"~"+answer+"~true";
            }

        }
        else
        {
            if(answer.equals("null"))
            {
                return this.question+"~"+""+"~true";
            }
            else
            {
                return this.question+"~"+answer+"~false";
            }

        }
    }
}
class Question
{
    int number;//题目序号
    int score;//题目分值
    public Question(int number, int score)
    {
        this.number = number;
        this.score = score;
    }
}
class ExamPaper//试卷类
{
    public int examnumber;//试卷号
    public List questions;
    public ExamPaper(int examnumber)
    {
        this.examnumber = examnumber;
        this.questions = new ArrayList<>();
    }
    public void addQuestion(Question question)
    {
        questions.add(question);
    }
    public String toString()
    {
        int sum=0;
        for (Question question:this.questions)
        {
            sum=sum+question.score;
        }
        if(sum!=100)
        {
            return "alert: full score of test paper"+this.examnumber+" is not 100 points";
        }
        else
        {
            return " ";
        }
    }
}
class AnswerPaper//答卷类
{
    public int papernumber;
    public String num;//学号
    public HashMap answers;//试卷序号和题目答案
    public AnswerPaper(int papernumber,String num)
    {
        this.papernumber = papernumber;
        this.num=num;
        this.answers = new HashMap();
    }
    public void addAnswer(int number,String answer)
    {
        answers.put(number,answer);
    }
}
class Student
{
    public String num;//学号
    public String name;//姓名
    public Student(String num,String name)
    {
        this.num=num;
        this.name=name;
    }
}
public class Main
{
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        HashMap Issues= new HashMap();//题目类哈希表
        HashMap ExamPapers= new HashMap();//试卷类哈希表
        List AnswerPapers = new ArrayList<>();//答卷类列表
        HashMap Students= new HashMap();//学生类哈希表
        List del = new ArrayList<>();//删除题目列表
        List wrong = new ArrayList<>();//错误格式列表
        while (true)
        {
            String line = input.nextLine();
            if (line.equalsIgnoreCase("end"))
            {
                break;
            }
            if (line.startsWith("#N:"))//存储题目类
            {
                Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.+) #A:");
                Pattern pattern1 = Pattern.compile("#A:(.+)");
                Matcher matcher = pattern.matcher(line);
                Matcher matcher1 = pattern1.matcher(line);
                Issue issue = new Issue();;
                if(matcher.find())
                {
                    issue.number = Integer.parseInt(matcher.group(1));
                    issue.question = matcher.group(2);
                    if(matcher1.find())
                    {
                        issue.answer = matcher1.group(1);
                    }
                    else
                    {
                        issue.answer="null";
                    }
                    Issues.put(issue.number,issue);
                    issue = null;
                }
                else
                {
                    wrong.add("wrong format:"+line);
                }

            }
            else if (line.startsWith("#T:"))//试卷类
            {
                Question a = null;
                ExamPaper a1 = null;
                Pattern p = Pattern.compile("#T:(\\d) (\\d+)-");//试卷编号
                Matcher m = p.matcher(line);
                if(m.find())
                {
                    Pattern p1 = Pattern.compile("#T:(\\d+)");//试卷编号
                    Matcher m1 = p1.matcher(line);
                    if (m1.find())
                    {
                        a1 = new ExamPaper(Integer.parseInt(m1.group(1)));
                        line = line.replaceFirst("#T:\\d+\\s+", "");
                        Pattern p2 = Pattern.compile("(\\d+)-(\\d+)");//获取题目序号和分值
                        Matcher m2 = p2.matcher(line);
                        while (m2.find())
                        {
                            a = new Question(Integer.parseInt(m2.group(1)), Integer.parseInt(m2.group(2)));
                            a1.addQuestion(a);
                            a = null;
                        }
                        ExamPapers.put(a1.examnumber,a1);
                        a1 = null;
                    }
                }
                else
                {
                    wrong.add("wrong format:"+line);
                }

            }
            else if (line.startsWith("#S:"))//获取答卷信息
            {
                AnswerPaper a = null;
                Pattern p1 = Pattern.compile("#S:(\\d+)\\s(\\S+)");
                Matcher m1 = p1.matcher(line);
                if (m1.find())
                {
                    a = new AnswerPaper(Integer.parseInt(m1.group(1)),m1.group(2));
                    line = line.replaceFirst("#S:\\d+\\s\\S+\\s+", "");
                    Pattern p2 = Pattern.compile("#A:(\\S+)");
                    Pattern p3 = Pattern.compile("#A:(\\S+)-(\\S+)");
                    Matcher m2 = p2.matcher(line);
                    Matcher m3 = p3.matcher(line);
                    while (m2.find())
                    {
                        if(m3.find())
                        {
                            a.addAnswer(Integer.parseInt(m3.group(1)), m3.group(2));//存入试卷题目序号和题目答案
                        }
                        else
                        {
                            a.addAnswer(Integer.parseInt(m2.group(1)), "null");//存入试卷题目序号和题目答案
                        }
                    }
                }
                else
                {
                    wrong.add("wrong format:"+line);
                }
                AnswerPapers.add(a);
                a = null;
            }
            else if(line.startsWith("#X:"))
            {
                Student a = null;
                line = line.replaceFirst("#X:", "");
                Pattern p1 = Pattern.compile("(\\d+)\\s(\\w+)");
                Matcher m1 = p1.matcher(line);
                while(m1.find())
                {
                    a = new Student(m1.group(1),m1.group(2));
                    Students.put(a.num,a);
                    a = null;
                }
            }
            else if(line.startsWith("#D:"))
            {
                Pattern p1 = Pattern.compile("N-(\\d+)");
                Matcher m1 = p1.matcher(line);
                while(m1.find())
                {
                    del.add(Integer.parseInt(m1.group(1)));
                }
            }
            else
            {
                if(line != null&&!line.isEmpty())
                {
                    wrong.add("wrong format:"+line);
                }
            }
        }
        for(String a : wrong)
        {
            System.out.println(a);
        }
        for (Map.Entry entry : ExamPapers.entrySet())//打印是否试卷有100分
        {
            if(!entry.getValue().toString().equals(" "))
            {
                System.out.println(entry.getValue().toString());
            }
        }
        for (AnswerPaper answerpaper : AnswerPapers)//答卷列表
        {
            int sum=0;
            StringBuilder sb = new StringBuilder();
            if(ExamPapers.containsKey(answerpaper.papernumber))//找到匹配的试卷
            {
                int t=1;//用t来表示试卷中题目顺序
                for(Question question : ExamPapers.get(answerpaper.papernumber).questions)//试卷中题目顺序
                {
                    if(answerpaper.answers.containsKey(t))//这个题目是否在答卷中存在
                    {
                        if(Issues.containsKey(question.number))//是否引用错误题号
                        {
                            if(del.contains(question.number))//是否题号被删除
                            {
                                sb.append("0 ");
                                System.out.println("the question "+ question.number+" invalid~0");
                            }
                            else
                            {
                                if(Issues.get(question.number).check(answerpaper.answers.get(t)))
                                {
                                    sum=sum+question.score;
                                    sb.append(question.score+" ");
                                }
                                else
                                {
                                    sb.append("0 ");
                                }
                                System.out.println(Issues.get(question.number).toString(answerpaper.answers.get(t)));
                            }
                        }
                        else
                        {
                            sb.append("0 ");
                            System.out.println("non-existent question~0");
                        }
                    }
                    else//这个题目答案为空
                    {
                        sb.append("0 ");
                        System.out.println("answer is null");
                    }
                    t++;//指向下一题
                }
                if(Students.containsKey(answerpaper.num))//判断是否存在这个学号
                {
                    String sb1=sb.toString().trim();
                    System.out.println(answerpaper.num+" "+Students.get(answerpaper.num).name+": "+sb1+"~"+sum);
                }
                else
                {
                    System.out.println(answerpaper.num+" not found");
                }
            }
            else//没找到这个答卷
            {
                System.out.println("The test paper number does not exist");
            }
        }
    }
}

    

分析
Issue 类:表示一个问题/题目,具有题号、问题和标准答案。它有一个检查答案并生成字符串表示的方法。
Question 类:表示考试试卷上的问题,具有题号和分数。
ExamPaper 类:表示一张考试试卷,具有试卷编号和问题列表。它有一个计算试卷总分的方法。
AnswerPaper 类:表示学生的答卷,具有答卷编号、学生ID和问题编号与答案的映射。
Student 类:表示一个学生,具有学生ID和姓名。
Main 类:包含了命令行应用程序的主方法。它从用户输入中读取数据,对其进行解析,并根据输入执行操作。
该程序使用正则表达式来解析以特定标识符开头的输入行,如#N:、#T:、#S:、#X:和#D:。这些标识符似乎代表与问题、考试试卷、答卷、学生和删除问题相关的不同类型的输入。
程序然后处理输入,存储有关问题、考试试卷、答卷、学生和已删除问题的信息。它还检查输入中的格式错误。
最后,它执行操作,如计算考试试卷分数、检查学生答案,并打印结果。

三、踩坑心得
在编写答题判题程序时,要注意输入输出的格式和处理方式。确保程序能够正确读取和解析输入数据,并且能够输出正确的结果。要考虑各种可能出现的异常情况,并进行适当的异常处理。这样可以提高程序的健壮性和稳定性。在处理大量数据时,要注意内存的管理和优化。避免内存泄漏和不必要的内存占用,以提高程序的性能和效率。要进行充分的测试和调试。确保程序能够正确运行,并且能够处理各种情况下的输入数据。

四、改进建议
根据题目的要求和数据规模,选择合适的数据结构和算法来解决问题。优化算法可以提高程序的效率和性能。编写清晰、简洁的代码,并添加适当的注释来解释代码的逻辑和功能。这样可以提高代码的可读性和可维护性。将程序拆分成多个模块或函数,每个模块负责一个特定的功能。这样可以降低代码的复杂度,方便测试和调试。考虑使用一些Java开发工具和框架来简化开发过程,提高开发效率。
要考虑安全性问题,避免出现安全漏洞。

五、总结
数据输入:设计一个合适的数据输入方式,可以通过命令行参数、文件输入、网络输入等方式读取题目和答案数据。
数据处理:对于读取到的题目和答案数据,需要进行相应的处理,例如解析题目内容、验证答案的正确性等操作。
答题逻辑:设计答题逻辑,根据题目内容和要求,编写相应的算法逻辑来判定答案的正确性。
输出结果:根据判定结果,设计合适的输出方式,可以将结果输出到命令行、文件、数据库等。
异常处理:考虑可能出现的异常情况,如数据格式错误、文件读取失败等,编写相应的异常处理逻辑。
测试和调试:在编写完程序后,进行充分的测试和调试,确保程序能够正确地读取数据、处理数据、判定答案并输出结果。
优化性能:对程序进行性能优化,减少不必要的计算和内存消耗,提高程序的效率和稳定性。