PTA题目集6-8的总结性博客

发布时间 2023-06-24 00:15:24作者: 欧阳东

一、前言

  第三次在博客园上发布面向对象程序设计(Java)的题目集总结blog。这一系列题目是关于课程成绩统计程序,主要用于计算和输出学生的成绩信息。

  • 关于知识点:

        三次作业主要是运用Java的基本语法知识,例如:选择、循环、数组、方法等内容,以及组合聚合等各种java关系。语法知识基本与C语言一致,除了一些表达方式不同,还有比如输入输出语句还有初始化数组等一些语句不同,因此写起来也更容易适应。而到了期中考试就是利用不同的关系,来实现想实现的功能。

  • 关于题量:

   题目数量不断减少,但是难度也在逐渐增加,所以花在写PTA上的时间总的来说还是不少,甚至会增加。部分题目集都需要设计类,对语言模式等结构需要掌握,独立思考,就需要对程序进行设计,不然会很混乱。前期其他课程的作业量也比较多,这种题量较为适中。

  • 关于难度:
  1. 第六·次作业难度分析: 根据题目描述,该课程成绩统计程序需要进行多个步骤的处理和计算,包括输入课程信息、课程成绩信息的解析,计算各种平均分并按规定格式输出。难度较高的地方在于对输入信息的解析和处理,以及对不同情况的判断和错误处理。
  2. 第七次作业难度分析: 相较于第一次的题目,课程成绩统计程序-2在添加了实验课程,并且实验课程成绩的计算方式与考试和考察不同。因此,该题目的难度相对较高。
  3. 第八次作业难度分析:相较于前两次的题目,课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,并将成绩类的继承关系改为组合关系。这个变化增加了对分项成绩的处理和权重的管理,使得程序的设计更加灵活和可扩展,但同时也增加了一定的复杂性。

二、设计与分析

  7-3 课程成绩统计程序-1

                                                                      类图:

代码如下:

复制代码
import java.text.Collator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static Scanner scanner = new Scanner(System.in);
    public static final Map<String, Course> courseMap = new TreeMap<>();
    public static final TreeSet<Student> students = new TreeSet<>();
    public static final List<StudentScore> scores = new ArrayList<>();
    public static final TreeSet<Ban> bans = new TreeSet<>();

    public static Student getStudent(Integer id, String name) {
        for (Student student : students) {
            if (student.id.equals(id) && student.name.equals(name)) {
                return student;
            }
        }

        Student student1 = new Student();
        student1.name = name;
        student1.id = id;
        students.add(student1);
        return student1;

    }

    public static Ban getBan(Integer code) {
        for (Ban ban : bans) {
            if (ban.code.equals(code)) {
                return ban;
            }
        }

        Ban ban = new Ban();
        ban.code = code;
        bans.add(ban);
        return ban;
    }

    public static void main(String[] args) {
        while (true) {
            String input = scanner.nextLine();
            String[] s = input.split(" ");
            if (input.matches("(.*?)\\s+(必修|选修)\\s+(考试|考察)$")) {
                if (s[0].length()>10){
                    System.out.println("wrong format");
                    continue;
                }
                Course course = new Course(s);
                if (course.bi&&!course.shi){
                    System.out.println(course.name+" : course type & access mode mismatch");
                    continue;
                }
                courseMap.put(course.name, course);
            } else if (input.matches("(\\d+)\\s+(\\S+)\\s+(.*?)\\s*(\\d*)\\s+(\\d+)$")) {
                if (s.length==5){
                    Integer pingshi = Integer.valueOf(s[3]);
                    Integer qimo = Integer.valueOf(s[4]);
                    if (pingshi>100||pingshi<0||qimo>100||qimo<0){
                        System.out.println("wrong format");
                        continue;
                    }
                }else if (s.length == 4){
                    Integer qimo = Integer.valueOf(s[3]);
                    if (qimo>100||qimo<0){
                        System.out.println("wrong format");
                        continue;
                    }
                }
                if (s[0].length()!=8){
                    System.out.println("wrong format");
                    continue;
                }
                if (s[1].length()>10){
                    System.out.println("wrong format");
                    continue;
                }
                if (s[2].length()>10){
                    System.out.println("wrong format");
                    continue;
                }
                StudentScore sc = new StudentScore();
                sc.student = getStudent(Integer.valueOf(s[0]), s[1]);
                sc.ban = getBan(Integer.valueOf((sc.student.id + "").substring(0,6)));
                sc.ban.students.add(sc.student);
                Course course = courseMap.get(s[2]);
                if (course != null) {
                    sc.course = course;
                }else {
                    System.out.println(s[2]+" does not exist");
                    continue;
                }
                if (s.length==5){
                    Integer pingshi = Integer.valueOf(s[3]);
                    Integer qimo = Integer.valueOf(s[4]);
                    if (pingshi>100||pingshi<0||qimo>100||qimo<0){
                        System.out.println("wrong format");
                        continue;
                    }
                    if (course.bi){
                        if (course.shi){
                            sc.pingshi = Integer.valueOf(s[3]);
                            sc.qimo = Integer.valueOf(s[4]);
                        }else {
                            System.out.println(sc.student.id+" "+sc.student.name+ " : course type & access mode mismatch");
                            continue;
                        }
                    }else {

                        if (course.shi){
                            sc.pingshi = Integer.valueOf(s[3]);
                            sc.qimo = Integer.valueOf(s[4]);
                        }else {
                            System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch");
                            continue;
                        }
                    }
                }else if (s.length == 4){
                    Integer qimo = Integer.valueOf(s[3]);
                    if (qimo>100||qimo<0){
                        System.out.println("wrong format");
                        continue;
                    }
                    if (course.bi){
                        if (course.shi){
                            System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch");
                            continue;
                        }else {
                            sc.qimo = Integer.valueOf(s[3]);
                        }
                    }else {
                        if (course.shi){
                            System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch");
                            continue;
                        }else {
                            sc.qimo = Integer.valueOf(s[3]);
                        }
                    }
                }
                scores.add(sc);
            } else if (input.equals("end")) {
                break;
            }
        }
        for (Student student : students) {
            Double all = 0.0;
            Double count = 0.0;
            for (StudentScore score : scores) {
                if (score.student.equals(student)) {
                    student.scores.add(score);
                    if (score.course.bi) {
                        if (score.course.shi) {
                            all +=  ((float) score.pingshi * 0.3);
                            all +=  ((float) score.qimo * 0.7);
                            count++;
                        } else {

                        }
                    } else {
                        if (score.course.shi) {
                            all += ((float) score.pingshi * 0.3);
                            all +=  ((float) score.qimo * 0.7);
                            count++;
                        } else {
                            count++;
                            all += score.qimo;
                        }
                    }
                }
            }
            if (count==0){
                System.out.println(student.id+" "+student.name+ " did not take any exams");
            }
            else {
                int val = (int) Math.floor(all / count);
                System.out.println(student.id + " " + student.name + " " + val);
            }
        }
        for (Course course : courseMap.values().stream().sorted().collect(Collectors.toList())) {
            Integer all = 0;
            Integer allmo = 0;
            Integer zong = 0;
            Integer count = 0;
            for (StudentScore score : scores) {
                if (score.course.equals(course)) {
                    if (course.shi) {
                        all += score.pingshi;
                        allmo += score.qimo;
                        count++;
                    } else {
                        allmo += score.qimo;
                        count++;
                    }
                }
            }
            if (count == 0) {
                System.out.println(course.name + " has no grades yet");
            } else {
                zong += all + allmo;
                Integer pingAll = (int) Math.floor((float) all / count);
                Integer pingMo = (int) Math.floor((float) allmo / count);
                if (course.shi) {
                    System.out.println(course.name + " " + pingAll + " " + pingMo + " " + (int) Math.floor(pingAll*0.3+pingMo*0.7));
                } else {
                    System.out.println(course.name + " " + pingMo + " " + pingMo);
                }
            }
        }
        for (Ban ban : bans) {
            Double all = 0.0;
            Double count = 0.0;
            for (Student student : ban.students) {
                for (StudentScore score : student.scores) {
                    if (score.course.bi) {
                        if (score.course.shi) {
                            all += (int) ((float) score.pingshi * 0.3);
                            all += (int) ((float) score.qimo * 0.7);
                            count++;
                        } else {

                        }
                    } else {
                        if (score.course.shi) {
                            all += (int) ((float) score.pingshi * 0.3);
                            all += (int) ((float) score.qimo * 0.7);
                            count++;
                        } else {
                            count++;
                            all += score.qimo;
                        }
                    }
                }
            }
            if (count == 0){
                System.out.println(ban.code + " has no grades yet");
                continue;
            }
            int val = (int) Math.floor(all / count);
            System.out.println(ban.code + " " + val);
        }

    }
}

class Course implements Comparable<Course>{
    String name;
    Boolean bi;
    Boolean shi;

    public Course(String[] s) {
        name = s[0];
        bi = s[1].equals("必修") ? true : false;
        if (s.length == 2 && bi) {
            shi = s[2].equals("考试") ? true : false;
        } else if (s.length == 3) {
            shi = s[2].equals("考试") ? true : false;
        }
    }

    @Override
    public int compareTo(Course o) {
        try {
            Comparator compator = Collator.getInstance(Locale.CHINA);
            if (compator.compare(name, o.name) < 0) {
                return -1;
            } else if (compator.compare(name, o.name) > 0) {
                return 1;
            }
        } catch (Exception e) {
        }
        return 0;
    }
}

class StudentScore {

    Student student = new Student();

    Course course;
    int pingshi;
    int qimo;

    Ban ban = new Ban();
}

class Ban implements Comparable<Ban> {
    Integer code;

    List<Student> students = new ArrayList<>();

    @Override
    public int compareTo(Ban o) {
        return code - o.code;
    }
}

class Student implements Comparable<Student> {
    String name;
    Integer id;

    List<StudentScore> scores = new ArrayList<>();

    @Override
    public int compareTo(Student o) {
        return this.id - o.id;
    }
}
复制代码

                                             SourceMonitor上代码质量分析结果:

 分析:

这段代码是一个课程成绩统计程序的实现。它使用Java语言编写,通过读取用户输入的信息来记录学生的课程成绩,并进行统计和输出。
代码主要逻辑在`main`方法中。首先,通过循环读取用户输入的每一行数据。根据输入的格式,判断是课程信息还是成绩信息。如果是课程信息,将其解析并存储到`courseMap`中;如果是成绩信息,将其解析并创建对应的`StudentScore`对象,然后存储到`scores`列表中。
在处理成绩信息时,通过调用`getStudent`和`getBan`方法获取或创建学生和班级对象,并将成绩信息与相应的学生、课程、班级关联起来。
接下来,通过遍历`students`列表,计算每个学生的平均成绩,并按照题目要求输出学生的学号、姓名和平均成绩。
然后,通过遍历`courseMap`中的课程信息,计算每门课程的平均分数,并按照题目要求输出课程的名称和平均分数。
最后,通过遍历`bans`列表,计算每个班级的平均成绩,并按照题目要求输出班级的编号和平均成绩。
整体而言,这段代码使用简单易懂的Java语言实现了课程成绩统计功能。通过合理的数据结构和逻辑处理,可以有效地记录、计算和输出学生的课程成绩信息。代码逻辑清晰,结构简洁,易于理解和使用。

  SourceMonitor上代码质量分析结果:

  • 代码结构良好,使用了合理的类和方法来组织逻辑。
  • 代码中包含了注释,有助于理解和阅读代码。
  • 使用了合适的数据结构来存储课程、学生和成绩信息。
  • 代码中没有明显的错误或潜在问题。
  • 对输入进行了一定程度的格式验证,但可能还可以进一步完善。

7-3 课程成绩统计程序-2

                                                        类图:

代码如下:

复制代码
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.Comparator;
import java.text.Collator;
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 {
            int num = Integer.parseInt(a[3]);
            int [] aaa =new int[num];
            for (int i = 0; i < aaa.length; i++) {
                aaa[i]=Integer.parseInt(a[i+4]);
            }
            score=new syScore(aaa,0,num);
        }
        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("实验")&&items.length-4==Integer.parseInt(items[3])){
            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 int getScore(ArrayList<Choose> courseSelects)//实验
    {
        int sum =0;
        for(Choose cs : courseSelects)
        {
            sum +=cs.score.getexperimentScore();
        }
        return sum/courseSelects.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() + " " + getScore(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 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 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;
    }
}
abstract class Score{
    public int Score2;//期末
    public int totalScore;
    //public int totalScore1;

    public int getTotalScore() {
        return totalScore;
    }

    public int getFinalScore() {
        return Score2;
    }

    public int getexperimentScore() {
        return totalScore;
    }

    Score(int finalScore){this.Score2=finalScore;}
}
class ksScore extends Score{
    private int Score1;//平时

    public int getUsualScore() {
        return Score1;
    }

    ksScore(int usualScore, int finalScore){
        super(finalScore);
        this.Score1=usualScore;
        this.totalScore=(int)(finalScore*0.7+usualScore*0.3);
    }
}
class kcScore extends Score{
    kcScore(int finalScore){
        super(finalScore);
        this.totalScore=finalScore;
    }
}
class syScore extends Score{
    syScore(int [] a,int finalScore,int n){
        super(finalScore);
        int sum=0;
        for (int i = 0; i <n; i++) {
            sum+=a[i];
        }
        this.totalScore=sum/n;
    }
}
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 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 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 scoreMatching1 = "([1-9]\\d{0,1}|0|100)( ([1-9]\\d{0,1}|0|100)){3,8}";
    static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符
    static String courseTypeMatching = "(选修|必修|实验)";
    static String checkcourseTypeMatching = "(考试|考察|实验)";
    static String experimentNumber = "[4-9]";
    //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 + " " + experimentNumber + " " +scoreMatching + " "+scoreMatching+ " "+scoreMatching;
    static String scoreInput3 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + experimentNumber +" "+scoreMatching1;
    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)||s.matches(scoreInput3));
    }
}
复制代码

 

                                                    SourceMonitor上代码质量分析结果:

 

 

 

 分析:

代码的主要逻辑在Main类中的main方法中,通过Scanner对象读取用户输入的每一行数据,并调用ParseInput类的parseInput方法进行解析和处理。根据不同的输入类型(课程信息或成绩信息),使用switch语句进行相应的处理。

ParseInput类包括了多个成员变量,分别存储课程、学生、选课和班级的信息列表。parseInput方法根据输入类型选择不同的处理方式,并调用相应的方法来解析和存储信息。

CourseStudentmyClass类分别表示课程、学生和班级的信息,在这些类中定义了相应的属性和方法。

在处理成绩信息时,inputScore方法根据输入的信息创建对应的CourseStudentScore对象,并将其添加到相应的列表中。同时,它也会进行一些错误检查,如判断课程名称是否存在、成绩数量与考核方式是否匹配等。

在最后,根据题目要求,使用showStudentsshowCoursesshowClasses方法分别输出学生、课程和班级的成绩信息。

整体而言,该代码实现了课程成绩统计程序的功能,通过多个类和方法进行数据的解析、存储和输出。代码中使用了合理的命名和注释,逻辑清晰,易于理解和维护。

  SourceMonitor上代码质量分析结果:

  • 代码结构相对清晰,逻辑较为简洁。
  • 使用了正则表达式进行输入格式匹配,提高了数据处理的准确性。
  • 通过引入新的类和方法,增加了代码的可读性和可维护性。
  • 对输入进行了更全面的错误检查,提供了更友好的错误提示。

7-2 课程成绩统计程序-3

                                                                         类图:

 代码如下:

复制代码
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
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 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 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 scoreMatching1 = "([1-9]\\d{0,1}|0|100)( ([1-9]\\d{0,1}|0|100)){1,9}";
    static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符
    static String courseTypeMatching = "(选修|必修|实验)";
    static String courseTypeMatching1 = "(选修|必修)";
    static String checkcourseTypeMatching = "(考试|考察|实验)";
    static String regex = "(\\d+\\.\\d+)( (\\d+\\.\\d+)){2,9}";
    static String experimentNumber = "[4-9]";
    static String qwer = "\\d+\\.\\d+";
    //cousrInput用于定义课程信息模式(正则表达式)
    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;

    static String courseInput0 = courseNameMatching + " " + courseTypeMatching1 + " " + "考试"+ " " + qwer + " " + qwer;

    static String courseInput1 = courseNameMatching + " " + "实验" + " " + "实验" + " " + experimentNumber + " " + regex;

    //scoreInput用于定义成绩信息模式(正则表达式)
    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching;

    static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching +" "+scoreMatching1;
    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)||s.matches(courseInput1)||s.matches(courseInput0));
    }
    private static boolean matchingScore(String s) {
        return (s.matches(scoreInput)||s.matches(scoreInput1));
    }
}
class Course implements Comparable<Course>{

    private String csName;
    private String csCharacter;
    private String csExamine;
    private int number;
    private double [] weight;

    public Course(String csName, String csCharacter, String csExamine,int number,double [] weight) {
        this.csName = csName;
        this.csCharacter = csCharacter;
        this.csExamine = csExamine;
        this.number = number;
        this.weight = weight;
    }

    public Course(String csName, String csCharacter, String csExamine,double [] weight) {
        this.csName = csName;
        this.csCharacter = csCharacter;
        this.csExamine = csExamine;
        this.weight = weight;
    }

    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;
    }

    public int getNumber() {
        return number;
    }

    public double[] getWeight() {
        return weight;
    }

    @Override
    public int compareTo(Course o) {
        Comparator<Object> compare = Collator.getInstance(Locale.CHINA);
        return compare.compare(csName,o.getCsName());
    }
}

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 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]),course.getWeight());
        }
        else {
            int num = a.length-3;
            int [] flag =new int[num];
            for (int i = 0; i < flag.length; i++) {
                flag[i]=Integer.parseInt(a[i+3]);
            }
            score=new syScore(flag,0,course.getWeight());
        }
        if(existChooseCourse(student,course)) return;
        Choose chooseCourse = new Choose(course, student, score);
        chooseArrayList.add(chooseCourse);
    }
    public void inputCourse(String[] a){
        Course course;
        double [] weight;
        if(a[2].equals("实验")&&a.length>7){
            weight = syweight(a);
            course = new Course(a[0],a[1],a[2],Integer.parseInt(a[3]),weight);
        }
        else {
            if (a[2].equals("考试")&&a.length==5)
            {
                weight = ksweight(a);
                course = new Course(a[0], a[1], a[2], weight);
            }
            else
                course = new Course(a[0],a[1],a[2]);
        }
        if(getCourse(a[0])!=null) return;
        if(!checkCourse(a,course)) return;
        if(getCourse(a[0])==null&&a[2].equals("考察")&&a.length==3){
            course=new Course(a[0], a[1], a[2]);
            courseArrayList.add(searchCourse(course));
        }
        if(getCourse(a[0])==null&&a[2].equals("实验")&&a.length>=8){
            weight = syweight(a);
            course=new Course(a[0], a[1], a[2],Integer.parseInt(a[3]),weight);
            courseArrayList.add(searchCourse(course));
        }
        if(getCourse(a[0])==null&&a[2].equals("考试")&&a.length==5){
            weight = ksweight(a);
            course=new Course(a[0], a[1], a[2],0,weight);
            courseArrayList.add(searchCourse(course));
        }
    }
    double[] ksweight(String[] b){
        double [] a = new double[2];
        for (int i = 0; i < a.length; i++) {
            a[i]=Float.parseFloat(b[i+3]);
        }
        return a;
    }
    double [] syweight(String[] b){
        double [] a = new double[Integer.parseInt(b[3])];
        for (int i = 0; i < a.length; i++) {
            a[i]= Float.parseFloat(b[i+4]);
        }
        return a;
    }
    boolean checkCourse(String[] items,Course course){
        if (items[2].equals("实验")&&items.length-4!=Integer.parseInt(items[3])){
            System.out.println(course.getCsName() + " : number of scores does not match");
            return false;
        }
        if (items[2].equals("实验")&&items.length-4==Integer.parseInt(items[3])){
            int num = Integer.parseInt(items[3]);
            double sum=0;
            int [] flag =new int[num];
            for (int i = 0; i < flag.length; i++) {
                sum+=Double.parseDouble(items[i+4]);
            }
            if(sum>1.000001||sum<0.999999){
                System.out.println(course.getCsName() + " : weight value error");
                return false;
            }
        }
        if (items[2].equals("考试")&&items.length==5){
            double sum= 0;
            int [] flag =new int[2];
            for (int i = 0; i < flag.length; i++) {
                sum+=Double.parseDouble(items[i+3]);
            }
            if(sum>1.000001||sum<0.999999){
                System.out.println(course.getCsName() + " : weight value error");
                return false;
            }
        }
        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().getStNumber().equals(stu.getStNumber()))
                    return true;
            }
        }
        return false;
    }
    Course searchCourse(Course course){
        for (Choose choose : chooseArrayList) {
            if (choose.getCourse().getCsName().equals(course.getCsName())) {
                return null;
            }
        }
        return course;
    }
    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("实验")&&items.length-3==course.getNumber()){
            return true;
        }
        System.out.println(items[0]+" "+items[1]+" : access mode mismatch");
        return false;
    }
    public int getAvgTotalScore(ArrayList<Choose> listChooseCourse)
    {
        int sum =0;
        for(Choose cs : listChooseCourse)
        {
            sum +=cs.score.getTotalScore();
        }
        return sum/listChooseCourse.size();
    }
    public int getScore(ArrayList<Choose> courseSelects)//实验
    {
        float sum =0;
        for(Choose cs : courseSelects)
        {
            sum +=cs.score.getExperimentScore();
        }
        return (int)(sum/courseSelects.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() + " " + getAvgTotalScore(CourseSelects));
                if (course.getCsExamine().equals("考察"))
                    System.out.println(course.getCsName() + " " + getAvgTotalScore(CourseSelects));
                if (course.getCsExamine().equals("实验"))
                    System.out.println(course.getCsName() + " " + getScore(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 Student implements Comparable<Student>{
    private String stuNumber;
    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());
    }
}
abstract class Score{
    public int Score2;//期末
    public int totalScore;
    public float getTotalScore() {
        return totalScore;
    }

    public float getExperimentScore() {
        return totalScore;
    }

    Score(int finalScore){this.Score2=finalScore;}
}
class ksScore extends Score{//考试
    private int Score1;//平时
    ksScore(int usualScore, int finalScore,double [] b){
        super(finalScore);
        this.Score1=usualScore;
        this.totalScore=(int)(Score1*b[0]+finalScore*b[1]);
    }
}
class kcScore extends Score{//考察
    kcScore(int finalScore){
        super(finalScore);
        this.totalScore=finalScore;
    }
}
class syScore extends Score{//实验
    syScore(int [] a,int finalScore,double [] b){
        super(finalScore);
        double sum=0;
        for (int i = 0; i <a.length; i++) {
            for (int j = 0; j < b.length; j++) {
                sum+=(a[i]*b[i]);
            }
        }
        this.totalScore= (int)sum/a.length;
    }
}
复制代码

                                           SourceMonitor上代码质量分析结果:

 

 

 分析:

这段代码是一个课程成绩统计程序的实现。它使用Java语言,通过读取用户输入的信息来记录课程和学生的成绩,并进行统计和输出。

主要逻辑在Main类的main方法中。它通过Scanner对象读取用户输入的每一行数据,并交给ParseInput类的parseInput方法处理。根据输入类型(课程信息或成绩信息),调用相应的方法来解析和存储信息。

ParseInput类包含了多个列表来存储课程、学生、选课和班级的信息。parseInput方法根据输入的内容选择不同的处理方式,并将解析后的信息存储到相应的列表中。

在处理成绩信息时,inputScore方法会根据输入的数据创建对应的CourseStudentScore对象,并将其添加到相应的列表中。同时,还进行了一些错误检查,如判断课程是否存在、成绩数量是否匹配等。

最后,调用showStudentsshowCoursesshowClasses方法按照题目要求输出学生、课程和班级的成绩信息。

整体而言,这段代码使用了简单易懂的Java语言来实现课程成绩统计功能。代码逻辑清晰,结构合理,易于理解和维护。

  SourceMonitor上代码质量分析结果:

  • 代码结构较为紧凑,逻辑清晰。
  • 使用了集合类型和Stream API,简化了代码的编写和处理。
  • 引入了新的类和方法,提高了代码的可拓展性和可复用性。
  • 对输入进行了更加详细和全面的错误检查。
  • 通过重构和优化,使得代码更加简洁、高效。

三、踩坑心得

  1. 题目:课程成绩统计程序

    • 踩坑心得:在处理输入时,需要注意对数据格式的合法性进行验证,以避免无效或错误的输入导致程序异常。
    • 潜在问题:代码中未对所有可能的非法输入进行全面的检查和处理,例如输入长度超过限制、输入范围不合理等。在实际应用中,应该更加严格地验证输入数据,并给出准确的错误提示。
  2. 题目:课程成绩统计程序的改进版

    • 踩坑心得:使用正则表达式可以有效地匹配和验证输入格式,提高了数据处理的准确性和可靠性。
    • 潜在问题:虽然使用了正则表达式进行输入验证,但仍然需要考虑到各种可能的输入情况。有些特殊情况可能无法通过简单的正则表达式来完全匹配,需要更全面地检查数据格式和范围。
  3. 题目:课程成绩统计程序的再次改进版

    • 踩坑心得:使用集合类型和Stream API可以简化代码编写,并提高代码的可读性和可维护性。
    • 潜在问题:虽然使用了集合类型和Stream API,但在处理大量数据时可能会影响性能。需要注意在实际应用中平衡代码的简洁性和性能需求,避免出现性能瓶颈。

四、改进建议

  1. 加强代码可读性和复用性:在编写代码时,应该遵循高内聚、低耦合的原则,将代码细分为一些独立的模块,减少重复代码和冗余代码。此外,通过好的命名方式和注释规范,能够有效提高代码可读性。
  2. 严格按照需求文档进行开发在编写代码之前,需要仔细阅读并理解需求文档的每个环节,审慎地思考其他模块之间的关系,确定所需的数据结构和算法。只有这样,才能切实有效地开发出符合要求的完整程序。对问题及时处理并推进项目进度在进行开发过程中,难免会遇到各种问题和挑战。良好的沟通协作是非常重要的,我们需要参与项目团队成员之间的讨论,共同找到最优解决方案,并及时处理问题以确保项目进度顺利。多掌握Java相关知识对于Java项目来说,更多的工具和技术链路会极大地提高代码效率。因此,在学习新的Java知识时,不妨尝试多做一些练习,比如熟悉集合框架、多线程编程、数据库操作等等,有助于更好地掌握Java相关知识。
  3. 不断接触新技术:Java 是一个广泛使用的编程语言,并且有很多与其匹配的开源技术。在学习Java时,需要考虑到前沿技术变化速度很快,千万不能只停留在表层。要不断地了解最新的 Java 技术和工具,跟上技术发展的步伐。

五、总结

    在通过Java作业的练习中,我深刻认识到了程序设计的重要性和学习Java编程的必要性。

  1. 理解项目需求及实现功能的逻辑,在开始做项目之前,需要仔细阅读每一个模块的需求文档,并理解这些需求如何与整个项目相关联。如果在这个阶段的理解不到位,就可能会出现后期代码失控、需求变更难以承担等问题。
  1. 处理各种迭代和继承关系,秉承面向对象的编程思想,Java中存在大量的迭代和继承关系。这对于初学者来说,可能会有一定难度,主要体现在类的设计、抽象方法、多态性等方面。
  1. 代码优化和效率,在Java开发过程中,为了项目的长期稳定性和可维护性,需要注意代码质量和效率的问题。因此,在写代码的时候,必须考虑到封装性、可读性、面向对象、重用性等一系列因素。

我的心得感受:在完成这样的Java项目时,需要具备扎实的Java基础知识,并要注重系统性思考和分析能力。同时,还需要注重团队协作和积极沟通,特别是多人协作开发时,用好 Git 版本控制工具来管理项目是非常重要的。任何一个步骤的缺陷会影响到整个开发的过程,因此,在完成每个模块之后都应该进行测试,确保代码稳定可靠,增强开发者对代码合理性和实现逻辑的信心。tq