南昌航空大学-23201406-第一次OOP博客作业

cyaytl / 2024-04-21 / 原文

这个Blog,主要是为了将在面向对象的程序设计课程(Java)中的前三次pta题目集进行一个总结。

一、前言

总结三次题目集的题目情况

关于题目集

这三次题目集的题量都不大,主要内容都集中在最后的判题程序中。且三次的难度循序渐进,充分起到了锻炼的作用。

题目本身

  1. 这三次题目集都强调了正则表达式的使用,要求通过正则表达式来对字符串进行操作。

  2. 类的设计的重要性也渐渐凸显出来,有一个好的设计可以使程序的修改比较容易实现,且程序更不容易出现难以预料到的错误。

  3. 编程的规范性也是考察的一部分,Java编程中的各种原则的重要性在写题的过程中也体现了出来,而对于不符合原则的代码,重构或许是最好的选择重构不完

二、设计与分析

对题目的提交源码进行分析,参考生成报表和类图

第一次题目集

第一次有五道题,但前四道只是初步考察了Java中类的使用,都是一次过的题,不做赘述。

第五题初看是有一点蒙的,主要是前面太容易,突然来了一个难的,题目也比较长,然后分值太高了,74啊,满分才100💦。然后仔细阅读题目后,发现题目难度并不是太大,主要是如何对输入的信息进行处理和收集。刚好当时老师正在强调正则的作用,题目中也提示了使用类,两个难题都解决了。

判题程序1源码
import java.util.Objects;
import java.util.Scanner;

class Topic {
    private int topicID;
    private String content;
    private String standAnswer;

    static Topic[] to = new Topic[100];

    public Topic() {}
    public Topic(int topicID, String content, String standAnswer) {
        this.topicID = topicID;
        this.content = content;
        this.standAnswer = standAnswer;
    }

    public int getTopicID() {
        return topicID;
    }

    public void setTopicID(int topicID) {
        this.topicID = topicID;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getStandAnswer() {
        return standAnswer;
    }

    public void setStandAnswer(String standAnswer) {
        this.standAnswer = standAnswer;
    }

    public boolean judgment(String answer) {
        return Objects.equals(answer, standAnswer);
    }
}

class Paper {
    private int num;
    private Topic topic = new Topic();

    Topic[] topics = Topic.to;
    public Paper() {}
    public Paper(int num) {
        this.num = num;

    }

    public int getNum() {
        return num;
    }

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

    public Topic getTopics(int num) {
        return topics[num - 1];
    }

    public void setTopics(int num) {
        for (int i = 0; i < num; i++) {
            topics[i] = new Topic(i + 1, "0", "0");
        }
    }

    public boolean judgment(int num, String answer) {
        return this.topics[num].judgment(answer);
    }

    public void save(int num, String question) {
        this.topics[num - 1].setContent(question);
    }

    public Topic getTopic() {
        return topic;
    }

    public void setTopic(Topic topic) {
        this.topic = topic;
    }
}

class Answer {
    private Paper paper = new Paper();
    private final String[] answer = new String[100];
    private boolean[] outcome;

    public Answer() {}
    public Answer(Paper paper) {
        this.paper = paper;
    }

    public Paper getPaper() {
        return paper;
    }

    public void setPaper() {
        this.paper = new Paper();
    }

    public String getAnswer(int num) {
        return answer[num - 1];
    }

    public void setAnswer(int num) {
        for (int i = 0; i < num; i++) {
            this.answer[i] = null;
        }
    }

    public boolean[] getOutcome() {
        return outcome;
    }

    public void setOutcome(boolean[] outcome) {
        this.outcome = outcome;
    }

    public boolean judgment(int num) {
        return paper.judgment(num - 1, getAnswer(num));
    }

    public String toString(int num) {
        return paper.getTopics(num).getContent() + "~" + getAnswer(num);
    }

    public void print(int num) {
        System.out.println(this.toString(num));
    }

    public void save(int num, String answer) {
        this.answer[num - 1] = answer;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int topicNum;
        String str1 = in.nextLine();
        topicNum = Integer.parseInt(str1);
        Answer answer = new Answer();
        answer.getPaper().setTopics(100);
        answer.setAnswer(100);
        for (int i = 1; i <= topicNum; i++){
            String str = in.nextLine();
            str = str.replaceAll("(\\s+|)#N:(\\s+|)", "#");
            str = str.replaceAll("(\\s+|)#Q:(\\s+|)", "#");
            str = str.replaceAll("(\\s+|)#A:(\\s+|)", "#");
            String[] str2 = str.split("#");
            int pos = Integer.parseInt(str2[1]);
            answer.getPaper().save(pos, str2[2]);
            answer.getPaper().getTopics(pos).setStandAnswer(str2[3]);
        }
        String str = in.nextLine();
        str = str.replaceAll("#A:", "");
        String[] str2 = str.split(" ");
        for (int i = 0; i < topicNum; i++) {
            answer.save(i + 1, str2[i]);
        }
        for (int i = 1; i <= topicNum; i++) {
            answer.print(i);
        }
        for (int i = 1; i <= topicNum; i++) {
            if (i == 1) {
                if (answer.judgment(i)) {
                    System.out.printf("true");
                } else {
                    System.out.printf("false");
                }
            } else {
                if (answer.judgment(i)) {
                    System.out.printf(" true");
                } else {
                    System.out.printf(" false");
                }
            }
        }
    }
}

类图

判题程序1类图

本次题目除开Main类外,一共写了三个类按照提示,分别为Answer(答案类)、Topic(题目类)、Paper(试卷类)。

Answer类用来存储输入信息中答卷的答案,Topic类用来存储输入信息中题目的信息,Paper用来使用Topic类的信息,并可操作Topic类对象,与Topic类相关联。

源码分析

判题程序1分析

可以看到,别的类都还好,但Main类的最大复杂度达到了11,代码已经算是复杂了。因为将输入的检测和输出是的判断都放入了Main类中,且没有做拆分,导致Main类中大量的for和if的存在,导致复杂度过大。

类中的函数的单一职责原则做的还是可以的,但是有些可以使用的函数忘了使用。比如Topic类中有一个判题函数,用来判断答案是否正确,但在程序中,直接使用了字符串的比较来判断对错,而没用函数,破坏了程序了结构,以后要注意这类问题。

第一次的判题程序并不是太难,主要是第一次见到,不熟悉。同时,对Java的了解也不是太深,没有认识的设计的重要性,导致程序过于臃肿,代码不够简便,思路不清晰,最后得到的也不是一个好的代码。

第二次题目集

第二次共有四道题目,除开第一题与Java中的Comparable有关,需要自己查找资料,重构函数外,二、三两题也没有什么可说的。

判题程序2源码
import java.util.*;

class Topic {
    private int topicID;
    private int score;
    private String content;
    private String standAnswer;
    private boolean right = false;

    public Topic() {}
    public Topic(int topicID, String content, String standAnswer) {
        this.topicID = topicID;
        this.content = content;
        this.standAnswer = standAnswer;
    }

    public int getTopicID() {
        return topicID;
    }

    public void setTopicID(int topicID) {
        this.topicID = topicID;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getStandAnswer() {
        return standAnswer;
    }

    public void setStandAnswer(String standAnswer) {
        this.standAnswer = standAnswer;
    }

    public boolean judgment(String answer) {
        return Objects.equals(answer, standAnswer);
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public boolean isRight() {
        return right;
    }

    public void setRight(boolean right) {
        this.right = right;
    }
}

class Answer {
    private int ar;
    private final String[] answer = new String[100];
    private boolean[] outcome;

    public Answer() {}

    public String getAnswer(int num) {
        return answer[num];
    }

    public void setAnswer(int num, String answer) {
        this.answer[num] = answer;
    }

    public boolean[] getOutcome() {
        return outcome;
    }

    public void setOutcome(boolean[] outcome) {
        this.outcome = outcome;
    }

    public int getAr() {
        return ar;
    }

    public void setAr(int ar) {
        this.ar = ar;
    }
}

class AnswerParer {
    private ArrayList<Answer> answers;

    public AnswerParer() {
        answers = new ArrayList<>(100);
        for (int i = 0; i < 100; i++) {
            answers.add(i, new Answer());
        }
    }

    public void setAnswers() {
        for (int i = 0; i < 100; i++) {
            answers.add(i, new Answer());
        }
    }

    public ArrayList<Answer> getAnswers() {
        return answers;
    }
}

class Paper {
    private int topic_num;
    private int score = 0;
    private int[] real_ar = new int[100];
    private ArrayList<Topic> topics;

    public Paper() {
        topics = new ArrayList<Topic>(100);
        for (int i = 0; i < 100; i++) {
            topics.add(i, new Topic());
        }
    }

    public void setTopics() {
        topics = new ArrayList<>(100);
    }

    public ArrayList<Topic> getTopics() {
        return topics;
    }

    public boolean judgment(int num, String answer) {
        return this.topics.get(num).judgment(answer);
    }

    public void save(int num, String question) {
        this.topics.get(num).setContent(question);
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score += score;
    }

    public int getTopic_num() {
        return topic_num;
    }

    public void setTopic_num(int topic_num) {
        this.topic_num = topic_num;
    }

    public int getReal_ar(int num) {
        return real_ar[num];
    }

    public void setReal_ar(int ar, int num) {
        real_ar[ar] = num;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int pos_paper = 1;
        int pos_answer = 0;
        int topic_num = 0;
        String[] str = new String[100];
        String str1, str2, str3;
        str1 = in.nextLine();
        ArrayList<Paper> papers = new ArrayList<>(100);
        AnswerParer answerParer = new AnswerParer();
        for (int i = 0; i < 100; i++) {
            papers.add(i, new Paper());
        }
        while (!Objects.equals(str1, "end")) {
            if (str1.matches("#N(.*)")) {
                topic_num++;
                str1 = str1.replaceAll("(\\s+|)#N:(\\s+|)", "#");
                str1 = str1.replaceAll("(\\s+|)#Q:(\\s+|)", "#");
                str1 = str1.replaceAll("(\\s+|)#A:(\\s+|)", "#");
                str = str1.split("#");
                for (int i = 0; i < 100; i++) {
                    papers.get(i).getTopics().get(Integer.parseInt(str[1]) - 1).setContent(str[2]);
                    papers.get(i).getTopics().get(Integer.parseInt(str[1]) - 1).setStandAnswer(str[3]);
                }
            }

            if (str1.matches("#T(.*)")) {
                str1 = str1.replaceAll("(\\s+|)#T:(\\s+|)", "#");
                str1 = str1.replaceAll("\\s+", "#");
                str = str1.split("[#\\s+-]+");
                pos_paper = Integer.parseInt(str[1]);
                for (int i = 3, j = 0; i <= str.length - 1; i += 2, j++) {
                    papers.get(pos_paper - 1).setScore(Integer.parseInt(str[i]));
                    papers.get(pos_paper - 1).getTopics().get(Integer.parseInt(str[i - 1])).setScore(Integer.parseInt(str[i]));
                    papers.get(pos_paper - 1).setReal_ar(j, Integer.parseInt(str[i - 1]));
                }
                papers.get(pos_answer).setTopic_num((str.length - 2) / 2);
                if (papers.get(pos_paper - 1).getScore() != 100) {
                    System.out.println("alert: full score of test paper"+ pos_paper +" is not 100 points");
                }
            }

            if (str1.matches("#S(.*)")) {
                str1 = str1.replaceAll("(\\s+|)#S:(\\s+|)", "#");
                str1 = str1.replaceAll("\\s+", "#");
                str1 = str1.replaceAll("A:", "#");
                str = str1.split("[#\\s]+");
                answerParer.getAnswers().get(pos_answer).setAr(Integer.parseInt(str[1]));
                for (int i = 2, j = 0; i < str.length; i++, j++) {
                    answerParer.getAnswers().get(pos_answer).setAnswer(j, str[i]);
                }
                pos_answer++;
            }

            str1 = in.nextLine();
        }

        for (int i = 0; i < pos_answer; i++) {
            int answer_pos = answerParer.getAnswers().get(i).getAr();
            if (answer_pos <= pos_paper) {
                for (int j = 0; j < papers.get(answer_pos - 1).getTopic_num(); j++) {
                    if (answerParer.getAnswers().get(i).getAnswer(j) == null) {
                        System.out.println("answer is null");
                    } else {
                        System.out.print(papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j) - 1).getContent() + "~" + answerParer.getAnswers().get(i).getAnswer(j) + "~");
                        if (Objects.equals(papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j) - 1).getStandAnswer(), answerParer.getAnswers().get(i).getAnswer(j))) {
                            System.out.println("true");
                            papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).setRight(true);
                        } else {
                            System.out.println("false");
                        }
                    }
                }
                for (int j = 0; j < papers.get(answer_pos - 1).getTopic_num(); j++) {
                    if (papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).isRight() && j == 0) {
                        System.out.print(papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).getScore());
                    }
                    if (!papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).isRight() && j == 0) {
                        System.out.print("0");
                    }
                    if (papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).isRight() && j != 0) {
                        System.out.print(" " + papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).getScore());
                    }
                    if (!papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).isRight() && j != 0) {
                        System.out.print(" 0");
                    }
                }
                int score = 0;
                for (int j = 0; j < papers.get(answer_pos - 1).getTopic_num(); j++) {
                    if (papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).isRight()) {
                        score += papers.get(answer_pos - 1).getTopics().get(papers.get(answer_pos - 1).getReal_ar(j)).getScore();
                    }
                }
                System.out.println("~" + score);
            } else {
                System.out.println("The test paper number does not exist");
            }
        }
    }
}

类图

判题程序2类图

相较于第一次的题目,本次题目在设计时加入了一个AnswerPaper类,因为答卷会变多,这个类用来存储不同的答卷,

源码分析

判题程序2分析

Main类的复杂度又变高了。。。但别的类复杂度却都很小,只能说设计的很失败,换句话说根本没有设计。将大量的判断和循环都塞进了Main类中,造出了一个有72个语句的方法,而没有考虑到后期的修改,为下一次的题目埋下了一些隐患。

相较于第一次的题目,这一次的难度提升并不算大,第一次提交之后就只差一个测试点了,再看看题目修改一下就过了。

但同时过得快的弊端就是我没有太过深入地思考题目想让我们干什么。对于设计的忽视让我的程序过于臃肿,写之前其实也是想过要重构一下代码的,但是过了后也就不了了之了。

第三次题目集

第三次题目集只有三道题,第一题考察了类的封装性,第二题考察了对于Java中日期类的一些基本使用就是测试点有点抽象难。

判题程序3源码
import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;

class Topic {
    private int ID;
    private int score;
    private String content;
    private String standAnswer;

    private boolean effective = true;

    public Topic() {}

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setStandAnswer(String standAnswer) {
        this.standAnswer = standAnswer;
    }

    public boolean isEffective() {
        return effective;
    }

    public void setEffective(boolean effective) {
        this.effective = effective;
    }

    public boolean judgment(String answer) {
        return Objects.equals(answer, this.standAnswer);
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }
}

class Answer {
    private int ar;
    private String ID;
    private int[] answerArray = new int[100];
    private final String[] answer = new String[100];

    public Answer() {}

    public String getAnswer(int num) {
        return answer[num];
    }

    public void setAnswer(int num, String answer) {
        this.answer[num] = answer;
    }

    public int getAr() {
        return ar;
    }

    public void setAr(int ar) {
        this.ar = ar;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public int getArray(int pos) {
        return answerArray[pos];
    }

    public void setArray( int pos, int num) {
        this.answerArray[pos] = num;
    }
}

class AnswerParer {
    private ArrayList<Answer> answers;

    public AnswerParer() {
        answers = new ArrayList<>(100);
        for (int i = 0; i < 100; i++) {
            answers.add(i, new Answer());
        }
    }

    public ArrayList<Answer> getAnswers() {
        return answers;
    }
}

class Paper {
    private int topicNum;
    private int score = 0;
    private int[] realAr = new int[100];
    private int[] topicArray = new int[100];
    private ArrayList<Topic> topics;

    public Paper() {
        topics = new ArrayList<>(100);
        for (int i = 0; i < 100; i++) {
            topics.add(i, new Topic());
        }
    }

    public ArrayList<Topic> getTopics() {
        return topics;
    }

    public boolean judgment(int num, String answer) {
        if (getTopics().get(num).judgment(answer) && getTopics().get(num).isEffective()) {
            this.score += getTopics().get(num).getScore();
            return true;
        } else {
            return false;
        }
    }

    public void saveScore(int num, int score) {
        this.topics.get(num).setScore(score);
    }

    public int getScore() {
        return score;
    }

    public int getTopicNum() {
        return topicNum;
    }

    public void setTopicNum(int topicNum) {
        this.topicNum = topicNum;
    }

    public int getRealAr(int num) {
        return realAr[num];
    }

    public void setRealAr(int ar, int num) {
        realAr[ar] = num;
    }

    public int getTopicArray(int pos) {
        return topicArray[pos];
    }

    public void setTopicArray(int pos, int num) {
        topicArray[pos] = num;
    }
}

class Student {
    private String name;
    private String ID;

    public Student() {}
    public Student(String name, String ID) {
        this.name = name;
        this.ID = ID;
    }

    public String getName() {
        return name;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }
}

class Input {

    private int posPaper = 1;

    public int getPosAnswer() {
        return posAnswer;
    }

    public int getStudentNum() {
        return studentNum;
    }

    public int getPaperArray(int pos) {
        return paperArray[pos];
    }

    public ArrayList<Paper> getPapers() {
        return papers;
    }

    private int posAnswer = 0;
    private int topicNum = 0;
    private int studentNum = 0;

    public AnswerParer getAnswerParer() {
        return answerParer;
    }

    private int[] paperArray = new int[100];
    private ArrayList<Paper> papers = new ArrayList<>(100);

    public ArrayList<Student> getStudents() {
        return students;
    }

    private ArrayList<Student> students = new ArrayList<>(100);
    private AnswerParer answerParer = new AnswerParer();

    public Input(ArrayList<Paper> papers, ArrayList<Student> students, AnswerParer answerParer) {
        for (int i = 0; i < 100; i++) {
            papers.add(i, new Paper());
            students.add(i, new Student());
        }
        this.papers = papers;
        this.students = students;
        this.answerParer = answerParer;
    }

    public void getMassage() {
        Scanner in = new Scanner(System.in);

        int ar = 0;
        String[] str = new String[100];
        String str1;
        str1 = in.nextLine();
        for (int i = 0; i < 100; i++) {
            papers.add(i, new Paper());
        }
        while (!Objects.equals(str1, "end")) {
            if (str1.matches("#N:\\d(.*) #Q:(.*|) #A:(.*|)")) {
                String tem = str1;
                if (str1.matches("(.*)#Q:(.*)")) {
                    str1 = str1.replaceAll("#N:", " #");
                    str1 = str1.replaceAll("#Q:", "#");
                    str1 = str1.replaceAll("#A:$", "#A:" + "@");
                    str1 = str1.replaceAll("#A:(\\s+|)", "#");
                    if (str1.matches("(.*)##(.*)")) {
                        System.out.println("wrong format:" + tem);
                    } else {
                        topicNum++;
                        str = str1.split("( #)");
                        for (int j = 0; j < str.length; j++) {
                            if (Objects.equals(str[j], "@")) {
                                str[j] = "";
                            }
                        }
                        str[3] = str[3].replaceAll("\\s+$","");
                        for (int i = 0; i < 100; i++) {
                            papers.get(i).getTopics().get(Integer.parseInt(str[1]) - 1).setContent(str[2]);
                            papers.get(i).getTopics().get(Integer.parseInt(str[1]) - 1).setStandAnswer(str[3]);
                            papers.get(i).setTopicArray(topicNum - 1, Integer.parseInt(str[1]));
                        }
                    }
                } else {
                    System.out.println("wrong format:" + str1);
                }
            } else if (str1.matches("#T:\\d+( \\d+-\\d+)+")) {
                if (str1.matches("(.*)(?<=(\\D|\\s))-(.*)") || str1.matches("(.*)-(?=\\D+|\\s+)(.*)") || str1.matches("(.*)-") || !str1.matches("(.*)-(.*)")) {
                    System.out.println("wrong format:" + str1);
                } else {
                    str1 = str1.replaceAll("(\\s+|)#T:(\\s+|)", "#");
                    str1 = str1.replaceAll("\\s+", "#");
                    str = str1.split("[#\\s+-]+");
                    posPaper = Integer.parseInt(str[1]);
                    paperArray[ar] = Integer.parseInt(str[1]);
                    ar++;
                    int score = 0;
                    for (int i = 3, j = 0;i <= str.length - 1; i += 2, j++) {
                        score += Integer.parseInt(str[i]);
                        papers.get(posPaper - 1).saveScore(Integer.parseInt(str[i - 1]) - 1, Integer.parseInt(str[i]));
                        papers.get(posPaper - 1).setRealAr(j, Integer.parseInt(str[i - 1]));
                    }
                    papers.get(posPaper - 1).setTopicNum((str.length - 2) / 2);
                    if (score != 100) {
                        System.out.println("alert: full score of test paper" + posPaper + " is not 100 points");
                    }
                }
            } else if (str1.matches("#S:\\d+ \\d+(.*)")) {
                String tem = str1;
                if (str1.matches("(.*)(?<=(\\D))-(.*)")) {
                    System.out.println("wrong format:" + str1);
                } else {
                    str1 = str1.replaceAll("(?<=[^\\s+])#", " #");
                    str1 = str1.replaceAll("#S:", " #");
                    str1 = str1.replaceAll("#A:", "#");
                    str1 = str1.replaceAll("(\\d)\\s+(\\d{8})", "$1 #$2");
                    str1 = str1.replaceAll("-(?=#)", "-@ ");
                    str1 = str1.replaceAll("-(?=$)", "-@");
                    str = str1.split("( #)|-");
                    for (int i = 0; i < str.length; i++) {
                        if (Objects.equals(str[i], "@")) {
                            str[i] = "";
                        }
                    }
                    if (str.length > 2) {
                        answerParer.getAnswers().get(posAnswer).setAr(Integer.parseInt(str[1]));
                        answerParer.getAnswers().get(posAnswer).setID(str[2]);
                        for (int i = 3, j = 0; i < str.length; i += 2, j++) {
                            str[i + 1] = str[i + 1].replaceAll("\\s+$","");
                            answerParer.getAnswers().get(posAnswer).setAnswer(Integer.parseInt(str[i]) - 1, str[i + 1]);
                            answerParer.getAnswers().get(posAnswer).setArray(j, Integer.parseInt(str[i]));
                        }
                    }
                    else {
                        System.out.println("wrong format:" + tem);
                    }
                    posAnswer++;
                }
            } else if (str1.matches("#X:\\d+ [a-zA-Z]+(-\\d+ [a-zA-Z]+)*")) {
                if (str1.matches("(.*)(?<![a-zA-Z])-(.*)") || str1.matches("(.*)-(?=\\D+|\\s+)(.*)") || str1.matches("(.*)-")) {
                    System.out.println("wrong format:" + str1);
                } else {
                    str1 = str1.replaceAll("(\\s+|)#X:(\\s+|)", "");
                    str = str1.split("[-\\s#]");
                    for (int i = 1; i < str.length; i += 2) {
                        students.add(studentNum, new Student(str[i], str[i - 1]));
                        studentNum++;
                    }
                }
            } else if (str1.matches("#D:N-\\d+")){
                str1 = str1.replaceAll("(\\s+|)#D:(\\s+|)", "");
                str1 = str1.replaceAll("\\s+", "");
                str = str1.split("[-\\s#]");
                for (int i = 0; i < 100; i++) {
                    papers.get(i).getTopics().get(Integer.parseInt(str[1]) - 1).setEffective(false);
                }
            }
            else {
                System.out.println("wrong format:" + str1);
            }
            str1 = in.nextLine();
        }
    }
}

class Judgment {
    private ArrayList<Paper> papers = new ArrayList<>(100);
    private ArrayList<Student> students = new ArrayList<>(100);
    private ArrayList<String> strings = new ArrayList<>();
    private AnswerParer answerParer = new AnswerParer();
    private Input input = new Input(papers, students, answerParer);

    public Judgment(ArrayList<Paper> papers, ArrayList<Student> students, AnswerParer answerParer) {
        for(int i = 0; i < 100; i++) {
            papers.add(i, new Paper());
            students.add(i, new Student());
        }
        this.papers = papers;
        this.students = students;
        this.answerParer = answerParer;
    }



    public void getMassage() {
        input.getMassage();
    }

    public void getOutcome() {
        boolean bo1 = false;
        boolean bo2 = false;
        boolean bo3 = false;
        boolean bo4 = false;

        for (int i = 0; i < input.getPosAnswer(); i++) {
            int answerPos = input.getAnswerParer().getAnswers().get(i).getAr();
            for (int j = 0; j < 100; j++) {
                if (answerPos == input.getPaperArray(j)) {
                    bo4 = true;
                    break;
                }
            }
            if (bo4) {
                for (int j = 0; j < input.getPapers().get(answerPos - 1).getTopicNum(); j++) {
                    for (int n = 0; n < 100; n++) {
                        if ((input.getAnswerParer().getAnswers().get(i).getArray(n) == j + 1)) {
                            bo2 = true;
                            break;
                        }
                    }
                    if (bo2) {
                        for (int n = 0; n < 100; n++) {
                            if (input.getPapers().get(answerPos - 1).getRealAr(j) == input.getPapers().get(answerPos - 1).getTopicArray(n)) {
                                bo3 = true;
                                break;
                            }
                        }
                        if (bo3) {
                            if (input.getPapers().get(answerPos - 1).getTopics().get(input.getPapers().get(answerPos - 1).getRealAr(j) - 1).isEffective()) {
                                System.out.print(input.getPapers().get(answerPos - 1).getTopics().get(input.getPapers().get(answerPos - 1).getRealAr(j) - 1).getContent() + "~");
                                System.out.print(input.getAnswerParer().getAnswers().get(i).getAnswer(j) + "~");
                                if (input.getPapers().get(answerPos - 1).judgment(input.getPapers().get(answerPos - 1).getRealAr(j) - 1, input.getAnswerParer().getAnswers().get(i).getAnswer(j))) {
                                    System.out.println("true");
                                    strings.add(" " + input.getPapers().get(answerPos - 1).getTopics().get(input.getPapers().get(answerPos - 1).getRealAr(j) - 1).getScore());
                                } else {
                                    System.out.println("false");
                                    strings.add(" 0");
                                }
                            } else {
                                System.out.println("the question " +  input.getPapers().get(answerPos - 1).getRealAr(j) + " invalid~0");
                                strings.add(" 0");
                            }
                            bo3 = false;
                        } else {
                            System.out.println("non-existent question~0");
                            strings.add(" 0");
                        }
                        bo2 = false;
                    } else {
                        System.out.println("answer is null");
                        strings.add(" 0");
                    }
                }
                for (int j = 0; j < input.getStudentNum(); j++) {
                    if (Objects.equals(input.getAnswerParer().getAnswers().get(i).getID(), input.getStudents().get(j).getID())) {
                        bo1 = true;
                        System.out.print(input.getStudents().get(j).getID() + " " + input.getStudents().get(j).getName() + ":");
                        break;
                    }
                }
                if (bo1) {
                    for (String string : strings) {
                        System.out.print(string);
                    }
                    System.out.println("~" + input.getPapers().get(answerPos - 1).getScore());
                    bo1 = false;
                } else {
                    System.out.println(input.getAnswerParer().getAnswers().get(i).getID() + " not found");
                }
                bo4 = false;
            } else {
                System.out.println("The test paper number does not exist");
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        ArrayList<Paper> papers = new ArrayList<>(100);
        ArrayList<Student> students = new ArrayList<>(100);
        AnswerParer answerParer = new AnswerParer();
        Judgment judgment = new Judgment(papers, students, answerParer);

        judgment.getMassage();
        judgment.getOutcome();
    }
}

类图

判题程序3类图

此次,增加了Judgment类,将前两次Main类中方法中移动了进去;Input类,重写了输入的检测方法;Student类,用来存储新增加的学生信息。

源码分析

判题程序3分析

前三次没有整理好代码结构的弊端暴露了出来,抓紧对代码进行了重构,不仅添加了及几个新的类,将代码中的逻辑也改了一部分。

输入的检测有些复杂,导致Input的最大复杂度达到了36,下次将会把检测的标准拆分出来,应该可以将复杂度降下来。

输出的判断没有拆分出来,留在了Judgment类中,导致Judgment类的复杂度也不低。

这次题目的难度不仅仅在结构的设计上,代码的严谨性、规范性也是要注意的,有些人的代码一次就过了,但也有人怎么都过不了。好在最后测试点改了,代码没改就过了。总之难度还是不低的。

踩坑心得

对出现的问题及心得进行总结

设计方面

这一系列题目,最大的目的就是强调要加强对于代码结构的设计的和其本身的规范性。

经过这三次的题目集,也算是理解了好的结构的作用了,总有一些人写的很快。因为他们的代码的结构够好,不需要大动干戈,只用在理解题目的要求后,加上新的信息,再将已有的输入检测和输出条件修改和就行了;而代码结构不好的人,就要牵一发而动全身了。

一开始并没有意识到结构的重要性,导致在第三次题目集中浪费了很多精力和时间。

格式判断

第三次的判题程序需要检测非常多的错误格式判断,我的思路出了一些问题,第一次判断时没有用严格的判段,导致在后面要多加一些不要的if语句。Input类的复杂度大也有这方面的一些问题。

以后着这样的判断条件要尽量做到精简、高效,减少不必要的复杂度。

细节处理

第三次题目集的第二个题目中有个要求需要比较日期来实现。起初,没有考虑周到,将比较条件设置错了,最后还是偶然换了函数才过,只能说还是要仔细看题,好好思考。

第三次判题程序修改了很多次,也和细节处理的不好有写关系,有很多的测试点是一次又一次试过去的,如果可以有耐心还好琢磨一下细节的话,应该可以省去一些时间。

好多人卡在答案为空字符这个测试点上,但有些人第一次提交时,这个测试点就过了。

臃余代码

在写判题程序3时,发现了许多的没用用到的代码。

甚至于有些自己都不知道是什么,才意识到是上一次的要解决问题时,有思路时写的,但后来有了另外的想法,那些代码就搁置了。导致代码中有一些不必要的部分,

以后遇到这样的问题应当及时处理,或用注释标记出来,而不是放着不管。

改进建议

给出自己的改进见解,做到可持续改进

结构优化

  1. 改善现有的类的结构,以便于下次题目集的继承与多态的实现。

  2. 将类进行拆分,功能进行细化,便于修改。

  3. 添加一些控制类,减少代码的耦合度。

  4. 可以为检测和判断新创建一个类,降低复杂度。

代码优化

  1. 将输入的检查进行修改,使其精简。

  2. 现在对于字符串的处理中有一些臃余的代码,可以以在不影响功能的情况下做点修改。

  3. 有些函数的使用不太规范,也是要改进的点。

其他方面

  1. 要注意自己编程的过程,确保规范性。

  2. 写完后检查一下,看看是否有比较明显的,可以改进的地方。

  3. 在自己并不确定的地方,可以先用注释标记下来,先写别的地方。

虽然三次的题目都拿到了满分,但是代码有些臃肿,结构也不尽人意,最终的分估计也不会拿满,下次一定要改好不好的,争取达到课程的要求。

总结

本阶段三次题目集的综合性总结,和对教学方面的建议

自己感想

这三次题目集,别的方面涉及的其实并不多,只是稍微提到了一些接口和日期类的知识。

主要还是围绕着正则表达式和类的设计来进行能力的检测。

好的正则表达式不仅让人容易理解,对于字符串的处理也很强,很容易就可以提升代码效率。现在正则了解的差不多了,但设计一个很好的正则表达式还是不太容易,还是要加紧学习。

另一个方面就是类的设计,现在我对这方面的学习还是不够到位,我现在只是初步了解,并没有深入钻研,程序的结构还没有搞好。但下一次的题目要用到继承与多态,我程序的结构还并不支持我比较方便的进行继承,所以说我再写下一次的题目之前还是要先进行重构。

此外,对面向对象的编程时的几个原则也有了更深一层的了解,这三次题目集,涉及的还只有单一职责这一个原则。但下一次,随着继承的加入,其余几个职责的作用也会显现出来,在下一次题目出来前,也要抽时间在去研究,确保遵守。

建议及意见

  1. 除开判题程序外,别的题可以适当涉及多的方面,考察一下自学能力。

  2. 题目关闭后,可以适当放出一点测试点,以便了解当时到底错在哪了。

  3. 可以设置些小组作业,以便熟悉Java中的团队合作。