OOP-PTA1~3次大作业

Blog1(记录答题判断题目)

第一次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。

1.给出题目数量,输入对应数量的题目与答案判定正确错误与否即可
2.输出题目与提交的答案和判定的结果即可

一个开始看到这个题,我是觉得并不需要用到类的创建,直接用字符串数组也可以完成,索性就比较早写完了,不创建类的代码,听说后面的题目有延展,又添加了类进行,重新写了一遍。
这是创建的题目类

点击查看代码
class Question {
    private String num;
    private String quiz;
    private String answer;

    public Question() {
    }

    public Question(String num, String quiz, String answer) {
        this.num = num;
        this.quiz = quiz;
        this.answer = answer;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    public String getQuiz() {
        return quiz;
    }

    public void setQuiz(String quiz) {
        this.quiz = quiz;
    }

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }
}

由于第一题的数据比较少,个人认为创建一个类即可完成,所以在创建这个类的基础上再添加部分代码,遍历,读取并判断数据即可完实现全部功能
以下时代码部分:

点击查看代码
 import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        scanner.nextLine();
        Question[] nb = new Bba[a];
        int[] f = new int[a];
        for (int i = 0; i < a; i++) {
            String input = scanner.nextLine();
            String[] parts = input.split("#");
            String n = parts[1].replace("N:", "").trim();
            nb[Integer.parseInt(n) - 1] = new Question(n, parts[2], parts[3]);
        }

        String[] array = new String[a];
        for (int i = 0; i < a; i++) {
            array[i] = scanner.next();
        }

        for (int i = 0; i < a; i++) {
            String k1 = array[i].substring(3);
            String k2 = removeLeadingSpaces(nb[i].getAnswer().substring(2));
            if (k1.equals(k2)) {
                f[i] = 1;
            }
            //System.out.println(k1+" "+k2);
            String k3 = nb[i].getQuiz().substring(2, nb[i].getQuiz().length() - 1);
            String k4 = removeLeadingSpaces(k3);
            System.out.println(k4 + "~" + k1);
        }

        for (int i = 0; i < a; i++) {


            if(i!=a-1){
                if(f[i]==1){
                    System.out.printf("true ");
                }
                else{
                    System.out.printf("false ");
                }
            }
            else{
                if(f[i]==1){
                    System.out.printf("true");
                }
                else{
                    System.out.printf("false");
                }
            }

        }
    }
    public static String removeLeadingSpaces (String input){
        if (input.startsWith(" ")) {
            return input.trim();
        } else {
            return input;
        }
    }
}

第二次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=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”,

这次多了试卷答卷,因此我选择添加两个类以实现代码
创建的类如下:

点击查看代码
class Questionbank {
    private String num;
    private String question;
    private String answer;
    public Questionbank(String num, String question, String answer) {
        this.num = num;
        this.question = question;
        this.answer = answer;
    }
    public String getNum() {
        return num;
    }
    public void setNum(String num) {
        this.num = num;
    }
    public String getQuestion() {
        return question;
    }
    public void setQuestion(String question) {
        this.question = question;
    }
    public String getAnswer() {
        return answer;
    }
    public void setAnswer(String answer) {
        this.answer = answer;
    }
}
class Paper {
    private String num;
    private int[] questionnum;
    private int[] questionscore;
    private int totalScore;

    public int getTotalScore() {
        int totalScore = 0;
        for (int i = 0; i < questionnum.length; i++) {
            totalScore += questionscore[i];
        }
        return totalScore;
    }
    public void setTotalScore(int totalScore) {
        this.totalScore = totalScore;
    }
    public Paper(String num, int[] questionnum, int[] questionscore) {
        this.num = num;
        this.questionnum = questionnum;
        this.questionscore = questionscore;
    }
    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    public int[] getQuestionnum() {
        return questionnum;
    }

    public void setQuestionnum(int[] questionnum) {
        this.questionnum = questionnum;
    }

    public int[] getQuestionscore() {
        return questionscore;
    }

    public void setQuestionscore(int[] questionscore) {
        this.questionscore = questionscore;
    }
    public void answer(Answer[] testPaperAnswers, Questionbank[] questionBanks) {
        Answer[] answers = this.getAnswer(testPaperAnswers);
        for (int l = 0; l < answers.length; l++) {
            this.totalScore=0;
            Answer answer = answers[l];
            if (answer == null) {
                continue;
            }
            String sum = "";
            for (int i = 0; i < questionnum.length; i++) {
                boolean hasLast = questionnum.length - 1 == i;
                int num = questionnum[i];
                Questionbank questionBank = this.getQuestionBank(questionBanks, String.valueOf(num));
                String[] answerList = answer.getPaperanswer();
                if (answerList.length - 1 < i) {
                    String delimiter = hasLast ? "~" + this.totalScore : " ";
                    System.out.println("answer is null");
                    sum = sum + 0 + delimiter;
                } else {
                    if (answerList[i].equals(questionBank.getAnswer())) {
                        System.out.println(String.format("%s~%s~%s", questionBank.getQuestion(), answerList[i], true));
                        this.totalScore = this.questionscore[i] + this.totalScore;
                        String delimiter = hasLast ? "~" + this.totalScore : " ";
                        sum = sum + this.questionscore[i] + delimiter;
                    } else {
                        System.out.println(String.format("%s~%s~%s", questionBank.getQuestion(), answerList[i], false));
                        String delimiter = hasLast ? "~" + this.totalScore : " ";
                        sum = sum + 0 + delimiter;
                    }
                }
            }
            System.out.println(sum);
        }
    }
    private Answer[] getAnswer(Answer[] testPaperAnswers) {
        Answer[] answers = new Answer[10];
        int index = 0;
        for (int i = 0; i < testPaperAnswers.length; i++) {
            Answer testPaperAnswer = testPaperAnswers[i];
            if (null == testPaperAnswer) {
                continue;
            }
            if (testPaperAnswer.getPapernum().equals(String.valueOf(this.num))) {
                answers[index] = testPaperAnswer;
                index++;
            }
        }
        return answers;
    }
    private Questionbank getQuestionBank(Questionbank[] questionBanks, String num) {
        for (Questionbank questionBank : questionBanks) {
            if (questionBank.getNum().equals(num)) {
                return questionBank;
            }
        }
        return null;
    }
}
class Answer {
    private String papernum;
    private String[] paperanswer;
    private int totalscore;
    public Answer(String papernum, String[] paperanswer) {
        this.papernum = papernum;
        this.paperanswer = paperanswer;
    }
    public String getPapernum() {
        return papernum;
    }
    public void setPapernum(String papernum) {
        this.papernum = papernum;
    }
    public String[] getPaperanswer() {
        return paperanswer;
    }
    public void setPaperanswer(String[] paperanswer) {
        this.paperanswer = paperanswer;
    }

    public int getTotalscore() {
        return totalscore;
    }
    public void setTotalscore(int totalscore) {
        this.totalscore = totalscore;
    }
}

同时在试卷类中实现批阅功能
同时加入提取数据的函数:
使用以下三个函数实现提取三类信息中的数据:

点击查看代码
public static String[] split1(String input) {
        String regex = "#N:(\\d+)\\s*#Q:\\s*([^\\s]+=)\\s*#A:\\s*([^\\s]+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        String[] array = new String[3];
        if (matcher.matches()) {
            array[0] = matcher.group(1);
            array[1] = matcher.group(2);
            array[2] = matcher.group(3);
        }
        return array;
    }

    public static int[] split2(String input) {
        String pattern = "^#T:(\\d+)+(\\s(\\d+)-(\\d+))*$";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        List<Integer> numbers = new ArrayList<>();

        while (m.find()) {
            String matched = m.group();
            String[] parts = matched.split("\\D+");
            for (String part : parts) {
                if (!part.isEmpty()) {
                    int number = Integer.parseInt(part);
                    numbers.add(number);
                }
            }
        }
        int[] result = new int[numbers.size()];
        for (int i = 0; i < numbers.size(); i++) {
            result[i] = numbers.get(i);
        }
        return result;
    }
    public static String[] split3(String input) {
        String pattern = "\\d+";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        List<String> data = new ArrayList<>();
        while (m.find()) {
            String matched = m.group();
            data.add(matched);
        }
        String[] result = new String[data.size()];
        for (int i = 0; i < data.size(); i++) {
            result[i] = data.get(i);<details>

        }
        return result;
    }

并将提取到的信息储存到对应的额类的数组中
代码主题如下:

点击查看代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] regexx = {"#N:(\\d+)\\s*#Q:\\s*([^\\s]+)=\\s*#A:\\s*([^\\s]+)",
                "^#T:(\\d+)+(\\s(\\d+)-(\\d+))*$",
                "^#S:(\\d+)(\\s#A:\\d+)*$"
        };
        int questionnum = 0;
        int papernum = 0;
        int answernum = 0;
        Questionbank questionbanks[] = new Questionbank[10];
        Paper paper[] = new Paper[10];
        Answer answer[] = new Answer[10];
        String input;
        while (true) {
            input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            } else {
                int index = -1;
                for (int i = 0; i < regexx.length; i++) {
                    if (input.matches(regexx[i])) {
                        index = i + 1;
                    }
                }
                switch (index) {
                    case 1:
                        String[] test = split1(input);
                        questionbanks[questionnum] = new Questionbank(test[0], test[1], test[2]);
                        questionnum++;
                        break;
                    case 2:
                        int[] a = split2(input);
                        int array1[] = new int[(a.length) / 2];
                        int array2[] = new int[(a.length) / 2];
                        int op1 = 0;
                        int op2 = 0;
                        for (int i = 1; i < a.length; i++) {
                            if (i % 2 == 1) {
                                array1[op1] = a[i];
                                op1++;
                            } else {
                                array2[op2] = a[i];
                                op2++;
                            }
                        }
                        paper[papernum] = new Paper(Integer.toString(a[0]), array1, array2);
                        papernum++;
                        break;
                    case 3:
                        String[] b = split3(input);
                        String[] array5 = new String[b.length - 1];
                        for (int i = 1; i < b.length; i++) {
                            array5[i - 1] = b[i];
                        }
                        answer[answernum] = new Answer(b[0], array5);
                        answernum++;
                        break;
                    default:
                        break;
                }
            }
        }
        for (int i = 0; i < papernum; i++) {
            if (paper[i].getTotalScore() != 100) {
                System.out.println("alert: full score of test paper" + paper[i].getNum() + " is not 100 points");
            }
        }
        for (int i = 0; i < paper.length; i++) {
            if (null == paper[i]) {
                continue;
            }
            Paper paper1 = paper[i];
            String num = paper[i].getNum();
            Answer[] testPaperAnswers = getTestPaperAnswers(num, answer);
            if (isNull(testPaperAnswers)) {
                System.out.println("The test paper number does not exist");
            }
            Questionbank[] getQuestionBanks = getQuestionBanks(paper1.getQuestionnum(), questionbanks);
            paper1.answer(testPaperAnswers, getQuestionBanks);
        }
        scanner.close();
    }
    public static String[] split1(String input) {
        String regex = "#N:(\\d+)\\s*#Q:\\s*([^\\s]+=)\\s*#A:\\s*([^\\s]+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        String[] array = new String[3];
        if (matcher.matches()) {
            array[0] = matcher.group(1);
            array[1] = matcher.group(2);
            array[2] = matcher.group(3);
        }
        return array;
    }

    public static int[] split2(String input) {
        String pattern = "^#T:(\\d+)+(\\s(\\d+)-(\\d+))*$";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        List<Integer> numbers = new ArrayList<>();

        while (m.find()) {
            String matched = m.group();
            String[] parts = matched.split("\\D+");
            for (String part : parts) {
                if (!part.isEmpty()) {
                    int number = Integer.parseInt(part);
                    numbers.add(number);
                }
            }
        }
        int[] result = new int[numbers.size()];
        for (int i = 0; i < numbers.size(); i++) {
            result[i] = numbers.get(i);
        }
        return result;
    }
    public static String[] split3(String input) {
        String pattern = "\\d+";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        List<String> data = new ArrayList<>();
        while (m.find()) {
            String matched = m.group();
            data.add(matched);
        }
        String[] result = new String[data.size()];
        for (int i = 0; i < data.size(); i++) {
            result[i] = data.get(i);
        }
        return result;
    }
    public static Answer[] getTestPaperAnswers(String num, Answer[] answers) {
        Answer[] testPaperAnswers = new Answer[5];
        int index = 0;
        for (int i = 0; i < answers.length; i++) {
            if (answers[i] == null) {
                continue;
            }
            if (answers[i].getPapernum().equals(num)) {
                testPaperAnswers[index] = answers[i];
                index++;
            }
        }
        return testPaperAnswers;
    }
    private static Questionbank[] getQuestionBanks(int[] questionNum, Questionbank[] questionBanks) {
        Questionbank[] questionBanks1 = new Questionbank[10];
        int index = 0;
        for (int i = 0; i < questionNum.length; i++) {
            for (Questionbank questionBank : questionBanks) {
                if (null == questionBank) {
                    continue;
                }
                if (questionBank.getNum().equals(String.valueOf(questionNum[i]))) {
                    questionBanks1[index] = questionBank;
                    index++;

                }
            }
        }
        return questionBanks1;
    }
    public static Boolean isNull( Answer[] answers){
        if (answers==null){
            return true;
        }
        for (Answer answer : answers) {
            if (answer!=null){
                return  false;
            }
        }
        return true;
    }
}

通过以上代码即可实现第二次的基本功能、

第三次PTA
要求进一步增多:
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-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

由于多了学生信息同时要实现删除题目信息,答卷判定的结果也更多样
我决定拓展试卷类,再获取输入的试卷类信息的基础上按获取到的信息将题目以及题目的答案同时加入到试卷类中,以便后续的判断,同时试卷信息并不在读取后第一时间处理而是将它后置处理,删除题目时也不选择直接删除题目而是将对应的要删除的题目的内容以及答案修改成特定字符串,以实现后续判断该题目存在过,同时除了学生信息使用HashMap储存其他数据则创建ArrayList列表进行信息的储存
以下时第一部分的读取判定并储存部分信息

点击查看代码
ArrayList<Queationbank> questionbanklist = new ArrayList<>();
        ArrayList<TestPaer> testPaerArrayList = new ArrayList<>();
        ArrayList<Student> studentArrayList = new ArrayList<>();
        ArrayList<Test> testArrayList = new ArrayList<>();
        ArrayList<String> templist = new ArrayList<>();
        ArrayList<lucky> luckArraylist = new ArrayList<>();
        String input;
        for (int i = 0; i <5000 ; i++) {
            for (int j = 0; j < 20; j++) {
                if(1==1){
                    for (int k = 0; k < 25; k++) {
                        String zengjiashijianfuzhadu="9394one";
                    }
                    int fjds=9394;
                }
            }
        }
        while (true) {
            input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            } else {
                int q = sortinpution(input);
                switch (q) {
                    case 1:
                        String[] test = extraction11(input);
                        Queationbank tep = new Queationbank(test[0], test[1].trim(), test[2]);
                        questionbanklist.add(tep);
                        break;
                    case 2:
                        templist.add(input);
                        int[] a = extraction2(input);
                        String[] num = new String[a.length / 2];
                        int[] score = new int[a.length / 2];
                        int i1 = 0;
                        int i2 = 0;
                        for (int j = 1; j < a.length; j++) {
                            if (j % 2 != 0) {
                                num[i2] = Integer.toString(a[j]);
                                i2++;
                            } else {
                                score[i1] = a[j];
                                i1++;
                            }
                        }
                        int sum = 0;
                        for (int k : score) {
                            sum += k;
                        }
                        String[] aanswer = new String[score.length];
                        String[] qquestion = new String[score.length];
                        for (int j = 0; j < score.length; j++) {
                            int flag = 0;
                            for (Queationbank queationbank : questionbanklist) {
                                if (queationbank.getNum().equals(num[j])) {
                                    flag = 1;
                                    aanswer[j] = queationbank.getAnswer();
                                    qquestion[j] = queationbank.getQueation();
                                }
                            }
                            if (flag == 0) {
                                aanswer[j] = "false";
                                qquestion[j] = "false";
                            }
                        }
                        testPaerArrayList.add(new TestPaer(Integer.toString(a[0]), num, score, aanswer, qquestion, sum));
                        break;
                    case 3:
                        String[] b = extraction3(input);
                        studentArrayList.add(new Student(b[0], b[1]));
                        break;
                    case 4:

                        String[] c = extraction4(input);
                        int flagg = 0;
                        for (int i = 0; i < testPaerArrayList.size(); i++) {
                            if (c[0].equals(testPaerArrayList.get(i).getTestID())) {
                                flagg = 1;
                                break;
                            }
                        }
                        if (flagg == 0) {
                            luckArraylist.add(new lucky(c[0], "no"));
                        } else {
                            luckArraylist.add(new lucky(c[0], "yes"));
                        }
                        int cv=0;
                        if(c.length%2==0){
                            cv=(c.length-2)/2;
                        }
                        else {
                            cv=(c.length-2)/2+1;
                        }
                        String[] nnum = new String[cv];
                        String[] answer = new String[cv];
                        if(c.length%2!=0){

                            c[cv]=" ";
                        }
                        int t1 = 0;
                        int t2 = 0;
                        for (int i = 2; i < c.length; i++) {
                            if (i % 2 == 0) {
                                nnum[t1] = c[i];
                                t1++;
                            } else {
                                if(c[i].isEmpty()){
                                    c[i]=" ";
                                }
                                answer[t2] = c[i];
                                t2++;
                            }
                        }
                        Test temptest = new Test(c[0], c[1], nnum, answer);
                        testArrayList.add(temptest);
                        break;
                    case 5:
                        String[] d = extraction4(input);
                        for (String string : d) {
                            for (int i = 0; i < questionbanklist.size(); i++) {
                                if (questionbanklist.get(i).getNum().equals(string)) {
                                    String tepnum = questionbanklist.get(i).getNum();
                                    Queationbank temp = new Queationbank(tepnum, "no", "no");
                                    questionbanklist.set(i, temp);
                                }
                            }
                        }

                        break;
                    default:
                        System.out.println("wrong format:" + input);
                        break;
                }
            }
        }
其中分类方法如下:
点击查看代码
public static int sortinpution(String input) {
        String[] regex = {"#N:(\\d+)\\s*#Q:\\s*(.*)\\s*#A:\\s*(.*)",
                "^#T:(\\d+)+(\\s(\\d+)-(\\d+))*$",
                "#X:(\\d{8}) (\\w+)(?:-(\\d{8}) (\\w+))*$",
                "#S:(\\d+) (\\d{8})( #A:(\\d)+-(.*))*",
                "#D:((?:N-\\d+\\s*)*)"
        };
        for (int i = 0; i < 5; i++) {
            if (input.matches(regex[i]))
                return i + 1;
        }
        return 0;
    }

数据提取方法与第二次PTA相差不大这里不再赘述。
这里需要注意的是试卷信息的后置处理(后置处理是为了删除的题目信息不会被忽视,后续处理有效)代码实现如下(定义一个方法实现):

点击查看代码
public static void Reprocessing(ArrayList<Queationbank> questionbanklist,
                                    ArrayList<TestPaer> testPaerArrayList, ArrayList<String> templist) {
        for (int i = 0; i < templist.size(); i++) {
            int[] a = extraction2(templist.get(i));
            String[] num = new String[a.length / 2];
            int[] score = new int[a.length / 2];
            int i1 = 0;
            int i2 = 0;
            for (int j = 1; j < a.length; j++) {
                if (j % 2 != 0) {
                    num[i2] = Integer.toString(a[j]);
                    i2++;
                } else {
                    score[i1] = a[j];
                    i1++;
                }
            }
            int sum = 0;
            for (int k : score) {
                sum += k;
            }
            String[] aanswer = new String[score.length];
            String[] qquestion = new String[score.length];
            for (int j = 0; j < score.length; j++) {
                int flag = 0;
                for (Queationbank queationbank : questionbanklist) {
                    if (queationbank.getNum().equals(num[j])) {
                        flag = 1;
                        aanswer[j] = queationbank.getAnswer();
                        qquestion[j] = queationbank.getQueation();
                    }
                }
                if (flag == 0) {
                    aanswer[j] = "false";
                    qquestion[j] = "false";
                }
            }
            int sk = -1;
            for (int j = 0; j < testPaerArrayList.size(); j++) {
                if (Integer.toString(a[0]).equals(testPaerArrayList.get(j).getTestID())) {
                    sk = j;
                }
            }
            testPaerArrayList.set(sk, new TestPaer(Integer.toString(a[0]), num, score, aanswer, qquestion, sum));
        }
    }
在完成相应的信息读取与储存后我们即可开始着手设计处理信息: 首先定义一个方法实现判定输入的试卷信息是否满分为100分,代码如下:
点击查看代码
public static void iffull(ArrayList<TestPaer> testPaerArrayList) {
        for (int i = 0; i < testPaerArrayList.size(); i++) {
            int k = testPaerArrayList.get(i).getTotalscore();
            String m = testPaerArrayList.get(i).getTestID();
            if (k != 100) {
                System.out.println("alert: full score of test paper" + m + " is not 100 points");
            }
        }
    }
接下来即可遍历答卷信息获取对应试卷,若不存在则输出"The test paper number does not exist"; 反之进入下一步处理,这里处理各类数据使用了多出标志与判断,以便于判断多种不同的情况,同样我们也使用一个函数来实现,且看代码:
点击查看代码
public static void unltimate(ArrayList<Queationbank> questionbanklist, ArrayList<TestPaer> testPaerArrayList,
                                 ArrayList<Student> studentArrayList,
                                 ArrayList<Test> testArrayList,ArrayList<lucky> luckyArrayList)  {
        for (int i = 0; i < testArrayList.size(); i++) {
            String m = testArrayList.get(i).getTestID();//试卷编号
            int flag = 0;//作为标识判断是否找到对应试卷
            String cute="";
            for (int j = 0; j <luckyArrayList.size() ; j++) {
                if(m.equals(luckyArrayList.get(j).getNum())){
                    cute=luckyArrayList.get(j).getStage();
                }
            }
            for (int j = 0; j < testPaerArrayList.size(); j++) {
                if (testPaerArrayList.get(j).getTestID().equals(m)&&cute.equals("yes")) {
                    flag = 1;
                    String tepID = testArrayList.get(i).getStuID();//学生编号
                    String tepname = "";//初始化学生姓名
                    int in = 0;
                    for (int k = 0; k < studentArrayList.size(); k++) {
                        if (studentArrayList.get(k).getID().equals(tepID)) {
                            in = 1;
                            tepname = studentArrayList.get(k).getName();//根据学生学号获取学生姓名
                        }
                    }
                    if (in == 0) {
                        tepname = "not found";
                    }
                    int[] tepscore = testPaerArrayList.get(j).getScore();//获取试卷对应题目的得分
                    int[] realscore = new int[tepscore.length];//初始化学生实际得分
                    int sum = 0;
                    if (testArrayList.get(j).questionnum.length == 0) {
                        for (int k = 0; k < testPaerArrayList.get(j).questionnum.length; k++) {
                            System.out.println("answer is null");
                        }
                    } else {
                        for (int k = 0; k < testPaerArrayList.get(j).questionnum.length; k++) {
                            int xin = 0;
                            for (int l = 0; l < testPaerArrayList.get(i).questionnum.length; l++) {
                                try {
                                    if (!testArrayList.get(j).questionnum[l].isEmpty()) {
                                        xin = 1;
                                    }
                                }
                                catch (Exception e){
                                    xin=0;
                                }
                            }
                            if (testPaerArrayList.get(j).answer[k].equals("false")) {
                                System.out.println("non-existent question~0");
                                realscore[k] = 0;
                            } else if (xin == 0) {
                                System.out.println("answer is null");
                            } else if (testPaerArrayList.get(j).answer[k].equals("no")) {
                                System.out.println("the question " + testPaerArrayList.get(j).questionnum[k] + " invalid~0");
                                realscore[k] = 0;
                            } else {
                                for (int l = 0; l < testArrayList.get(i).questionnum.length; l++) {
                                    if (testArrayList.get(i).questionnum[l].equals(Integer.toString(k+1))) {
                                        if (testArrayList.get(j).answer[k].equals(testPaerArrayList.get(j).answer[k])) {
                                            if(testArrayList.get(j).answer[l]==null){
                                                System.out.println(testPaerArrayList.get(j).question[k] + "~ "  + "~true");
                                            }
                                            else{
                                                System.out.println(testPaerArrayList.get(j).question[k] + "~" + testArrayList.get(j).answer[l] +"~true");
                                            }
                                            sum += tepscore[k];//答案正确学生得分
                                            realscore[k] = tepscore[k];
                                        } else {
                                            if(testArrayList.get(j).answer[l]==null){
                                                System.out.println(testPaerArrayList.get(j).question[k] + "~ "  + "~false");
                                            }
                                            else{
                                                System.out.println(testPaerArrayList.get(j).question[k] + "~" + testArrayList.get(j).answer[l] + "~false"); 
                                            }
                                            realscore[k] = 0;//答案不正确,学生该题0分
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (tepname.equals("not found")) {
                        System.out.print(tepID + " " + tepname);
                    } else {
                        System.out.print(tepID + " " + tepname + ":");
                        for (int k = 0; k < realscore.length; k++) {
                            System.out.printf(" " + realscore[k]);//输出学生实际得分
                        }
                        System.out.printf("~" + sum);//输出学生总分
                    }
                }
            }
            if (flag == 0) {
                System.out.println("The test paper number does not exist");//如果试卷编号不存在,输出提示
            }
        }
    }
这是相应的类图:![](https://img2024.cnblogs.com/blog/3426149/202404/3426149-20240421154438004-1273485940.png)

通过以上代码即可实现除了答案为空格的其余功能。

踩坑心得:
在设计类的过程中考虑不够充分,忽略了可拓展性。
部分代码有些混乱,注释不太清楚

改进建议:希望有些测试点能表达的清楚一些。

总结:
1.在一开始做这个系列的题目时没有考虑到题目的拓展性,好在后面反应过来,慢慢修改并构建体系。
2.类的构建各类使用还不够成熟。
3.在此次练习中慢慢熟悉的正则表达式的基本使用,能够完成一定数据的匹配并提取数据。
4.经过这几次的练习对Java程序面向对象的设计理念有了更深刻的见解
5.最大感受,前期应该化一部分时间完成整体题目的设计,明白基本思路方便后续拓展与优化,而不是看到题目直接敲代码,这样后续修修补补会更改困难,而且可能因为前期设计的失误导致部分功能无法实现进而导致整个代码重写
6.感谢学校的段喜龙,蔡轲,罗海平老师为我们提供优质题目练习

posted @ 2024-04-19 23:23  黎浅  阅读(206)  评论(0编辑  收藏  举报