pta6-8次成绩管理系统作业总结

发布时间 2023-06-28 18:29:28作者: 流年似水亦穆

前言

  本次实验依旧运用了抽象类的知识点,并且结合了正则表达式进行考察;题目难度不算太大,格式识别中种种要求应接不暇,常常是顾此失彼,但只要确定好了各种字符串的正则表达式,许多问题都会迎刃而解;

 

设计与分析

这次把类设计的各个知识点都回顾了一遍,包括构造方法、方法重写、抽象类、继承、动态联编,这次作业是比较经典的面向对象练习,对思维是一种很好的锻炼;

 

类图:

 

 

 

源码:

import java.text.Collator;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.Locale;

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        String nextLine = input.nextLine();

        ParseInput handle=new ParseInput();

        while (!nextLine.equals("end")) {

            handle.parseInput(nextLine);//解析用户输入的每一行数据

            nextLine = input.nextLine();

        }

        handle.showStudents();

        handle.showCourses();

        handle.showClasses();

    }

}

class ParseInput{

    ArrayList<Course> courseArrayList = new ArrayList<>();

    ArrayList<Student> studentArrayList = new ArrayList<>();

    ArrayList<Choose> chooseArrayList = new ArrayList<>();

    ArrayList<myClass> classArrayList = new ArrayList<>();

    public void parseInput(String nextLine) {

        String[] arraylist = nextLine.split(" ");

        switch (InputMatching.matchingInput(nextLine)){

            case 1:

                inputCourse(arraylist);

                break;

            case 2:

                inputScore(arraylist);

                break;

            case 0:

                System.out.println("wrong format");

                break;

        }

    }

    Course getCourse(String courseName){

        for (Course course : courseArrayList) {

            if (course.getCsName().equals(courseName))

                return course;

        }

        return null;

    }

    myClass getClass(String classId){

        for (myClass myClass : classArrayList) {

            if (myClass.getID().equals(classId))

                return myClass;

        }

        return null;

    }

    Student getStudent(String stuId){

        for (Student student : studentArrayList) {

            if (student.getStNumber().equals(stuId))

                return student;

        }

        return null;

    }

    private void inputScore(String[] a){

        myClass myclass;

        Student student;

        myclass=getClass(a[0].substring(0,6));

        if(myclass==null){

            myclass=new myClass(a[0].substring(0,6));

            classArrayList.add(myclass);

        }

        student=getStudent(a[0]);

        if(student==null){

            student=new Student(a[0], a[1]);

            studentArrayList.add(student);

            myclass.addStudent(student);

        }

        Course course=getCourse(a[2]);

        if(course==null){

            System.out.println(a[2]+" does not exist");

            return;

        }

        if(!checkGrade(a,course))

            return;

        Score score;

        if(a.length==4){

            score=new kcScore(Integer.parseInt(a[3]));

        }else if(a.length==5){

            score=new ksScore(Integer.parseInt(a[3]),Integer.parseInt(a[4]));

        }else {

            ArrayList<Integer> exScores=new ArrayList<>();

            for (int i=4;i<a.length;i++)

                exScores.add(Integer.parseInt(a[i]));

            score=new exScore(exScores,Integer.parseInt(a[3]));

        }

        if(existChooseCourse(student,course)) return;//重复

        Choose chooseCourse = new Choose(course, student, score);

        chooseArrayList.add(chooseCourse);

    }

    public void inputCourse(String[] a){

        Course course = new Course(a[0],a[1],a[2]);

        if(!checkCourse(course))

            return;

        if(getCourse(a[0])==null){//没有重复的课程

            course=new Course(a[0], a[1], a[2]);

            courseArrayList.add(course);

        }

    }

    boolean checkCourse(Course course){

        if(course.getCsCharacter().equals("必修")&&course.getCsExamine().equals("考试"))

            return true;

        if(course.getCsCharacter().equals("选修")&&course.getCsExamine().equals("考试"))

            return true;

        if(course.getCsCharacter().equals("选修")&&course.getCsExamine().equals("考察"))

            return true;

        if(course.getCsCharacter().equals("实验")&&course.getCsExamine().equals("实验"))

            return true;

        System.out.println(course.getCsName()+" : course type & access mode mismatch");

        return false;

    }

    boolean existChooseCourse(Student stu,Course course){

        for (Choose choose : chooseArrayList) {

            if (choose.getCourse().getCsName().equals(course.getCsName())) {

                if (choose.getStudent().getStName().equals(stu.getStName()))

                    return true;

            }

        }

        return false;

    }

    private boolean checkGrade(String[] items,Course course){

        String courseType=course.getCsExamine();

        if(courseType.equals("考试")&&items.length==5){

            return true;

        }

        if(courseType.equals("考察")&&items.length==4){

            return true;

        }

        if(courseType.equals("实验")){

            if(items.length==Integer.parseInt(items[3])+4)

                return true;

        }

        System.out.println(items[0]+" "+items[1]+" : access mode mismatch");

        return false;

    }

    public static int getAvagScore1(ArrayList<Choose> courseSelects)//平时

    {

        int sum = 0;

        for(Choose cs : courseSelects)

        {

            sum +=((ksScore)(cs.score)).getUsualScore();

        }

        return sum/courseSelects.size();

    }

    public int getAvagScore2(ArrayList<Choose> courseSelects)//期末

    {

        int sum =0;

        for(Choose cs : courseSelects)

        {

            sum += cs.score.getFinalScore();

        }

        return sum/courseSelects.size();

    }

    public int getAvgTotalScore(ArrayList<Choose> listChooseCourse)

    {

        int sum =0;

        for(Choose cs : listChooseCourse)

        {

            sum +=cs.score.getTotalScore();

        }

        return sum/listChooseCourse.size();

    }

 

    public ArrayList<Choose> getStudentSelects(String stNumber) {

        ArrayList<Choose> stus = new ArrayList<>();

        for (Choose choose : chooseArrayList) {

            if (choose.student.getStNumber().equals(stNumber)) {

                stus.add(choose);

            }

        }

        if(stus.size()!=0)

            return stus;

        else return null;

    }

    public ArrayList<Choose> getCourseSelects(String courseName){

        ArrayList<Choose> courses = new ArrayList<>();

        for (Choose choose : chooseArrayList) {

            if (choose.course.getCsName().equals(courseName)) {

                courses.add(choose);

            }

        }

        if(courses.size()!=0)

            return courses;

        else return null;

    }

    public ArrayList<Choose> getClassSelects(String classID){

        ArrayList<Choose> classes = new ArrayList<>();

        for (Choose choose : chooseArrayList) {

            if (choose.student.getStNumber().substring(0, 6).equals(classID)) {

                classes.add(choose);

            }

        }

        if(classes.size()!=0)

            return classes;

        else return null;

    }

    public void showStudents() {

        Collections.sort(studentArrayList);

        for (Student student : studentArrayList) {

            ArrayList<Choose> stuCourseSelects = getStudentSelects(student.getStNumber());

            //从总选课表Choose中获取该生的选课记录集合

            if (stuCourseSelects != null) {

                System.out.println(student.getStNumber() + " " + student.getStName() + " " + getAvgTotalScore(stuCourseSelects));

            } else {

                System.out.println(student.getStNumber() + " " + student.getStName() + " " + "did not take any exams");

            }

        }

    }

    public void showCourses() {

        Collections.sort(courseArrayList);

        for (Course course : courseArrayList) {

            ArrayList<Choose> CourseSelects = getCourseSelects(course.getCsName());

            if (CourseSelects != null) {

                if (course.getCsExamine().equals("考试"))

                    System.out.println(course.getCsName() + " " + getAvagScore1(CourseSelects) + " " + getAvagScore2(CourseSelects) + " " + getAvgTotalScore(CourseSelects));

                if (course.getCsExamine().equals("考察"))

                    System.out.println(course.getCsName() + " " + getAvagScore2(CourseSelects) + " " + getAvgTotalScore(CourseSelects));

                if(course.getCsExamine().equals("实验"))

                    System.out.println(course.getCsName() + " " + getAvgTotalScore(CourseSelects));

            } else {

                System.out.println(course.getCsName() + " has no grades yet");

            }

        }

    }

    public void showClasses() {

        Collections.sort(classArrayList);

        for (myClass myClass : classArrayList) {

            ArrayList<Choose> stuClassSelects = getClassSelects(myClass.getID());

            if (stuClassSelects != null) {

                System.out.println(myClass.getID() + " " + getAvgTotalScore(stuClassSelects));

            } else {

                System.out.println(myClass.getID() + " " + "has no grades yet");

            }

        }

    }

}

class InputMatching {

    static String stuNumMatching = "[0-9]{8}";//8个0-9的数字

    static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符

    static String scoreMatching = "([1-9]?[0-9]|100)";

    static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符

    static String courseTypeMatching = "(选修|必修|实验)";

    static String checkcourseTypeMatching = "(考试|考察|实验)";

    static String exCountMatching="[4-9]";

    static String exScores="(([1-9]?\\d|100)\\s){3,8}([1-9]?\\d|100)";

    //cousrInput用于定义课程信息模式(正则表达式)

    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;

    //scoreInput用于定义成绩信息模式(正则表达式)

    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching;

    static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching;

    static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " "+exCountMatching+" "+exScores;

    public static int matchingInput(String s) {

        if (matchingCourse(s)) {

            return 1;

        }

        if (matchingScore(s)) {

            return 2;

        }

        return 0;

    }

    private static boolean matchingCourse(String s) {

        return s.matches(courseInput);

    }

    private static boolean matchingScore(String s) {

        return (s.matches(scoreInput) || s.matches(scoreInput1)||s.matches(scoreInput2));

    }

}

class Course implements Comparable<Course>{

    private String csName;

    private String csCharacter;

    private String csExamine;

    public Course(String csName, String csCharacter, String csExamine) {

        this.csName = csName;

        this.csCharacter = csCharacter;

        this.csExamine = csExamine;

    }

    public String getCsName() {

        return csName;

    }

    public String getCsCharacter() {

        return csCharacter;

    }

    public String getCsExamine() {

        return csExamine;

    }

    @Override

    public int compareTo(Course o) {

        Comparator<Object> compare = Collator.getInstance(Locale.CHINA);

        return compare.compare(csName,o.getCsName());

    }

}

class ksScore extends Score{//考试

    private int Score1;//平时

    public int getUsualScore() {

        return Score1;

    }

    public ksScore(int usualScore, int finalScore){

        super(finalScore);

        this.Score1=usualScore;

        this.totalScore=(int)(finalScore*0.7+usualScore*0.3);

    }

}

class exScore extends Score{

    ArrayList<Integer> exScores=new ArrayList<>();

    public exScore(ArrayList<Integer> exScores,int finalScore){

        super(finalScore);

        this.exScores=exScores;

        int sum=0;

        for (Integer exScore : this.exScores) {

            sum+=exScore;

        }

        finalScore=sum/exScores.size();

        this.totalScore=finalScore;

    }

}

class kcScore extends Score{//考察

    public kcScore(int finalScore){

        super(finalScore);

        this.totalScore=finalScore;

    }

}

class Student implements Comparable<Student>{

    private String stuNumber;

    private myClass myclass;

    private String stuName;

    public Student(String stuNumber, String stuName) {

        this.stuName=stuName;

        this.stuNumber=stuNumber;

    }

    public String getStNumber() {

        return stuNumber;

    }

    public String getStName() {

        return stuName;

    }

    @Override

    public int compareTo(Student student){

        return getStNumber().compareTo(student.getStNumber());

    }

}

class Choose {

    Course course;

    Student student;

    Score score;

    public Course getCourse() {

        return course;

    }

    public Student getStudent() {

        return student;

    }

    public Choose(Course course, Student student, Score score) {

        this.course = course;

        this.student = student;

        this.score = score;

    }

}

class myClass implements Comparable<myClass>{

    private String ID;

    ArrayList<Student> listStudent=new ArrayList<>();

    void addStudent(Student stu){

        listStudent.add(stu);

    }

    public myClass(String ID) {

        this.ID = ID;

    }

    public String getID() {

        return ID;

    }

    @Override

    public int compareTo(myClass myclass){

        return ID.compareTo(myclass.getID());

    }

}

class Score{

    protected int Score2;//期末

    protected int totalScore;

    public int getTotalScore() {

        return totalScore;

    }

    public int getFinalScore() {

        return Score2;

    }

    public Score(int finalScore) {

        this.Score2=finalScore;

    }

}

 

 

static String stuNumMatching = "[0-9]{8}";//8个0-9的数字

    static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符

    static String scoreMatching = "([1-9]?[0-9]|100)";

    static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符

    static String courseTypeMatching = "(选修|必修|实验)";

    static String checkcourseTypeMatching = "(考试|考察|实验)";

    static String exCountMatching="[4-9]";

    static String exScores="(([1-9]?\\d|100)\\s){3,8}([1-9]?\\d|100)";

 

该部分解决了输入格式的所有正确形式,使之后代码的编写变得更简单(主要是因为PTA八股文式的考察真的蛋疼);

 

class Score{

    protected int Score2;//期末

    protected int totalScore;

    public int getTotalScore() {

        return totalScore;

    }

    public int getFinalScore() {

        return Score2;

    }

    public Score(int finalScore) {

        this.Score2=finalScore;

    }

}

 

该部分给出成绩的成绩的父类,在计算考试和考察成绩时分别使用继承该类的子类即可;

 

 

踩坑心得

最先我尝试过对每个格式采取逐个相等的方法,过程相当麻烦,最后甚至超过了PTA的最大限度,并且在写完代码后,测试点确实是能过,但是格式错误无法从根本上解决,既然给出最大限度并出了题目,就说明有更简洁的方法可以完成相应的工作,在使用正则表达式后代码明显简洁了许多,并且解决了格式错误的问题;

首先我尝试的时在类里创建另外类的链表,在格式正确的情况下添加进链表中,我个人认为还是比较符合面向对象的思想,最后还是有些测试点解决不了,改进了几次,最后方案为,先进行格式判断,正确之后无论对错都添加进链表中,再经过一系列方法的筛选,最后打印出结果;

 

改进建议

可以将Score改成抽象类,代码量太大了,后续再添加成绩类型时可能会忘记一些方法,改成抽象类可以在编写时,不需要太注意分数的计算方法,在一定程度上帮助编写代码的实用性;

 

总结

本次作业,我个人进步最大的地方是学习了几个设计模式来辅助自己设计,这让我代码整体架构比较好,思路清晰,逻辑严谨。这次作业我也学到了多线程编程的基本方法;

本次实验中第一次接触了正则表达式,也体会到了正则表达式的强大,正则的效率挺高的,在很多情况下都能用到,对正则表达式更加熟练了;但是,还有许多地方有待进步,比如测试环节。设计模式也需要抓紧时间学习。