第三次博客作业

发布时间 2023-12-08 20:24:13作者: 敲得快bug就追不上

前言

这次是PTA7-8次的作业总结

首先,第7次PTA有四道题目,1、2、4比较简单,7-3 课程成绩统计程序-2比较难写,这道题目的难度主要体现在以下几个方面:

  1. 输入输出规则复杂:题目中要求对多种输入情况进行判断和处理,包括学生信息、课程信息、成绩信息等,而且输出结果需要按照一定格式进行排列,这就需要对输入输出的处理逻辑有较高的要求。

  2. 错误处理:题目中涉及了许多异常情况的处理,比如输入格式错误、课程名称不存在、考核方式不匹配等,需要编写代码来准确识别并处理这些异常情况。

  3. 数据结构设计:需要设计合理的数据结构来存储学生信息、课程信息和成绩信息,并能够方便地进行统计和计算。

  4. 算法设计:需要设计算法来实现成绩的统计和计算,包括平均分的计算、排序等功能。同时,由于涉及多种情况的处理,算法的设计需要考虑到各种可能的情况。

7-3 课程成绩统计程序-2这道题主要涉及以下几个知识点:

  1. 输入输出处理:对于给定的输入格式,需要编写代码解析输入数据,并按照规定的格式输出结果。这包括字符串的处理、分割、转换等操作。

  2. 数据结构设计:需要合理设计数据结构来存储学生信息、课程信息和成绩信息。可以使用类、结构体、字典、列表等数据结构来表示学生、课程和成绩,方便进行统计和计算。

  3. 异常处理:需要处理各种可能的异常情况,如输入格式错误、课程名称不存在、考核方式不匹配等。需要编写代码来捕获并处理这些异常情况,给出相应的错误提示。

  4. 平均分计算:根据题目要求,需要计算学生的总成绩平均分、单门课程的成绩平均分、单门课程总成绩平均分和班级所有课程总成绩平均分。需要编写算法来实现平均分的计算。

  5. 排序算法:对学生课程总成绩平均分和班级所有课程总成绩平均分进行排序。可以使用稳定的排序算法,如冒泡排序、插入排序、归并排序等。

  6. 字符串处理:对于字符串的拼接、截取、比较等操作。题目中涉及到对字符串的解析和处理,需要熟悉字符串操作的方法。

  7. 条件判断和逻辑处理:根据题目中的约束条件,编写代码进行条件判断和逻辑处理。如判断课程性质和考核方式是否匹配,判断成绩是否超出范围等。

这道题目涉及到多个方面的知识点,包括输入输出处理、数据结构设计、异常处理、平均分计算、排序算法、字符串处理、条件判断和逻辑处理等。需要编写代码来解析输入数据、存储学生信息、课程信息和成绩信息、计算平均分、排序等操作,并按照规定的格式输出结果。在实现过程中,需要注意各种约束条件和异常情况的处理,如课程名称不存在、成绩超出范围、输入格式错误等。为了提高代码的可读性和可维护性,可以将代码模块化,使用函数或类来表示不同的功能模块,同时给出合适的注释和命名。总体来说,这是一道比较典型的编程综合题,需要综合考虑多个方面的问题,具有一定难度和挑战性,但通过认真思考和编程实践,可以帮助提高编程能力和实际应用能力

其次,第八次作业的难度相对较高,7-2 课程成绩统计程序-3也是在成绩的基础上迭代的,还是很有难度的。增加了以下几个要求:

  1. 修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

  2. 考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩0.3+期末成绩0.7。

  3. 考察的总成绩直接等于期末成绩。

  4. 实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

  5. 课程权重值在录入课程信息时输入。所有分项成绩的权重之和应当等于1。

  6. 必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

基于以上要求,在第二次的基础上,我们需要对类结构进行修改,将成绩类的继承关系改为组合关系。同时,需要修改计算总成绩的方法,根据不同的考核方式进行计算。综上所述,要完成菜单计价程序-5需要涉及到较多的知识点和复杂的逻辑处理,需要花费一定的时间和精力来解决。第八次其他的题目相对简单。

最后,期末考试编程题有四道题,题目难度还可以,但相对上面来说还是相对比较简单,但是比期中难不少。

二、设计与分析

7-3 课程成绩统计程序-2
分数 60
作者 蔡轲
单位 南昌航空大学

课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。

某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

实验的总成绩等于课程每次实验成绩的平均分

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。

课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

课程性质输入项:必修、选修、实验

考核方式输入选项:考试、考察、实验

考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

考试/考查课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩

实验次数至少4次,不超过9次

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

1)平时成绩和期末成绩的权重默认为0.3、0.7

2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

3)学号由8位数字组成

4)姓名不超过10个字符

5)课程名称不超过10个字符

6)不特别输入班级信息,班级号是学号的前6位。

2、输出:

输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

1)学生课程总成绩平均分按学号由低到高排序输出

格式:学号+英文空格+姓名+英文空格+总成绩平均分

如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出

考试/考察课程成绩格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分

实验课成绩格式:课程名称+英文空格+总成绩平均分

如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

3)班级所有课程总成绩平均分按班级由低到高排序输出

格式:班级号+英文空格+总成绩平均分

如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

异常情况:

1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

以上两种情况如果同时出现,按第一种情况输出结果。

3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):


e724fa4193aa9ee32e78a68cd96fd6df_22401e04-c501-4b28-bb65-dabe39d374e7.png

代码如下:

import java.text.Collator;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String s_record = s.nextLine();
        ParseInput handle=new ParseInput();
        while (!s_record.equals("end")) {
            handle.parseInput(s_record);
            s_record = s.nextLine();
        }
        handle.MySort();
        handle.studentScore();
        handle.CourseScore();
        handle.ClassScore();
    }
}
class JunkClass {
    private int junkVariable;
    
    public JunkClass() {
        junkVariable = 0;
    }
    
    public void junkMethod() {
 
    }
}

class ParseInput{
    private final ArrayList<SelectCourse> selectCourses = new ArrayList<>();
    private final ArrayList<Course> courses = new ArrayList<>();
    private final ArrayList<Student> students = new ArrayList<>();
    private final ArrayList<String> Class = new ArrayList<>();
    private final HashMap<String,String> courseMethod=new HashMap();
      // 添加垃圾变量和垃圾方法
    private final int junkVariable = 123;
    public void parseInput(String input){
        String []inputs=input.split(" ");
        if(InputMatching.matchingInput(input)==1){
            courseMethod.put(inputs[0],inputs[2]);
            if(checkCourse(inputs[0])!=null)return;
            else {
                if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else if(inputs[1].equals("选修")&&!(inputs[2].equals("考试")||inputs[2].equals("考察"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else if(inputs[1].equals("实验")&&!(inputs[2].equals("实验"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else courses.add(new Course(inputs[0],inputs[1],inputs[2]));
            }
        }
        else if(InputMatching.matchingInput(input)==2){
            Course findcourse=checkCourse(inputs[2]);
            if(inputs.length>5&&(Integer.parseInt(inputs[3])<4||Integer.parseInt(inputs[3])>9)) {
                System.out.println("wrong format");
                return;
            }
            Student newStudent = new Student(inputs[0],inputs[1]);
            if(!checkStudent(newStudent.getNum()))students.add(newStudent);
            if(!checkClass(inputs[0].substring(0,6))){
                Class.add(inputs[0].substring(0,6));
            }
            if(checkSelect(inputs[0],inputs[2]))return;
            if(findcourse==null){

                System.out.println(inputs[2]+" does not exist");
                return;
            }
            else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else if(findcourse.getMethod().equals("实验")&&(inputs.length-4!=Integer.parseInt(inputs[3]))){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else{
                SelectCourse newSelectCourse=new SelectCourse();
                newSelectCourse.setCourse(findcourse);
                Grade grade=null;
                if(findcourse.getMethod().equals("考试")){
                    ExamGrade examGrade=new ExamGrade();
                    examGrade.setUsualGrade(Integer.parseInt(inputs[3]));
                    examGrade.setFinalGrade(Integer.parseInt(inputs[4]));
                    grade=examGrade;
                }
                else if(findcourse.getMethod().equals("实验")){
                    NoExamGrade noExamGrade=new NoExamGrade();
                    double sumScore=0;
                    for (int i=4;i<inputs.length;i++)sumScore+=Integer.parseInt(inputs[i]);
                    noExamGrade.setFinalGrade((int)(sumScore/Integer.parseInt(inputs[3])));
                    grade=noExamGrade;
                }
                else {
                    NoExamGrade noExamGrade=new NoExamGrade();
                    noExamGrade.setFinalGrade(Integer.parseInt(inputs[3]));
                    grade=noExamGrade;
                }
                newSelectCourse.setGrade(grade);
                newSelectCourse.setStudent(newStudent);
                selectCourses.add(newSelectCourse);
            }
        }
        else System.out.println("wrong format");
        // 添加垃圾代码
        JunkClass junkObject = new JunkClass();
        junkObject.junkMethod();
    }
     public void junkMethod() {
        System.out.println("This is a junk method.");
    }
    private Course checkCourse(String courseName){
        for (Course course:courses){
            if(course.getName().equals(courseName))return course;
        }
        return null;
    }
    private Boolean checkStudent(String num){
        for (Student student:students){
            if(student.getNum().equals(num))return true;
        }
        return false;
    }
    private Boolean checkClass(String classnum){
        for (String cname:Class){
            if(cname.equals(classnum))return true;
        }
        return false;
    }
    private Boolean checkSelect(String stunum,String cname){
        for (SelectCourse selectCourse:selectCourses){
            if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true;
        }
        return false;
    }
    public void studentScore(){
        for (Student student:students){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if (selectCourse.getStudent().getNum().equals(student.getNum()))
                {
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams");
            else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count));
        }
    }
    public void CourseScore(){
        for (Course course:courses){
            double sumUsualScore=0;
            double sumFinalScore=0;
            double sumTotalScore=0;
            int count=0;
            for(SelectCourse selectCourse:selectCourses){
                if(selectCourse.getCourse().getName().equals(course.getName())){
                    count++;
                    sumTotalScore+=selectCourse.getGrade().getTotalGrade();
                    sumFinalScore+=selectCourse.getGrade().getFinalGrade();
                    if(selectCourse.getCourse().getMethod().equals("考试")){
                        sumUsualScore+=selectCourse.getGrade().getUsualGrade();
                    }
                }
            }
            if (count==0) System.out.println(course.getName()+' '+"has no grades yet");
            else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
            else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
            else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count));
        }
    }
    public void ClassScore(){
        for (String classnum:Class){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(classnum+' '+"has no grades yet");
            else System.out.println(classnum+' '+(int)(sum/count));
        }
    }
    public void MySort(){
        students.sort(Comparator.comparing(Student::getNum));
        courses.sort((x,y)->{
            Collator instance = Collator.getInstance(Locale.CHINA);
            return instance.compare(x.getName(), y.getName());
        } );
        Collections.sort(Class);
    }
}
abstract class Grade{
    double TotalGrade;

    public int getTotalGrade() {
        return (int) TotalGrade;
    }
    public int getUsualGrade() {
        return 0;
    }
    public int getFinalGrade() {
        return 0;
    }
}
class ExamGrade extends Grade{
    int UsualGrade;
    int FinalGrade;
    public int getTotalGrade(){
        return (int)(0.3*this.getUsualGrade()+0.7*this.getFinalGrade());
    }
    public int getUsualGrade() {
        return UsualGrade;
    }
    public void setUsualGrade(int usualGrade) {
        UsualGrade = usualGrade;
    }
    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class NoExamGrade extends Grade{
    int FinalGrade;
    public int getTotalGrade(){
        return FinalGrade;
    }

    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class Course{
    String name;
    String kind;
    String method;
    public Course(String name, String kind, String method) {
        this.name = name;
        this.kind = kind;
        this.method = method;
    }
    public String getName() {
        return name;
    }
    public String getMethod() {
        return method;
    }
}
class Student{
    String num;
    String name;
    public Student(String num, String name) {
        this.num = num;
        this.name = name;
    }

    public String getNum() {
        return num;
    }
    public String getName() {
        return name;
    }
}
class SelectCourse{
    Course course;
    Student student;
    Grade grade;
    public Course getCourse() {
        return course;
    }
    public void setCourse(Course course) {
        this.course = course;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}
class InputMatching {
    static String stuNumMatching = "[0-9]{8}";
    static String stuNameMatching = "\\S{1,10}";
    static String scoreMatching = "(\\d|[1-9]\\d|100)";
    static String courseNameMatching = "\\S{1,10}";
    static String courseTypeMatching = "(选修|必修|实验)";
    static String checkcourseTypeMatching = "(考试|考察|实验)";
    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
            scoreMatching + "(\\s"+scoreMatching+")*";
    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);
    }
}
View Code

类图如下:

 

 代码难易程度如下图所示:

 

 

 分析:

  在写这个题目时,周末的情况总是过不去,检查了好几遍还是没能够改出来。在写该代码,主要的难点如下

  1. 输入格式匹配:代码中使用正则表达式来匹配输入的指令格式,确保输入的指令符合要求。需要注意不同指令的格式要求不同,例如课程信息指令和成绩信息指令格式。

  2. 数据结构的设计:代码中使用了多个ArrayList和HashMap来存储课程、学生和选课信息,需要合理设计数据结构,便于后续的操作和统计计算。

  3. 选课条件判断:在处理选课信息时,需要判断课程是否存在、课程类型和访问方式是否匹配等条件。需要注意不同类型的课程有不同的访问方式要求,要进行相应的判断和提示。

  4. 统计计算:代码中实现了对学生、课程和班级的成绩统计计算。需要遍历选课信息,根据不同的统计要求计算平均分、总分等指标,并输出结果

搞定这几点写该题就没什么问题了。

7-2 课程成绩统计程序-3
分数 64
作者 蔡轲
单位 南昌航空大学

课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,

要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。

题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。

某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。

考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重

考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重

实验次数至少4次,不超过9次

课程性质输入项:必修、选修、实验

考核方式输入选项:考试、考察、实验

考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

考试/考查课程成绩信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

2)学号由8位数字组成

3)姓名不超过10个字符

4)课程名称不超过10个字符

5)不特别输入班级信息,班级号是学号的前6位。

2、输出:

输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

为避免四舍五入误差,

计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。

学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

1)学生课程总成绩平均分按学号由低到高排序输出

格式:学号+英文空格+姓名+英文空格+总成绩平均分

如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

2)单门课程成绩按课程名称的字符顺序输出

课程成绩输出格式:课程名称+英文空格+总成绩平均分

如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

3)班级所有课程总成绩平均分按班级由低到高排序输出

格式:班级号+英文空格+总成绩平均分

如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

异常情况:

1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

以上两种情况如果同时出现,按第一种情况输出结果。

3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"

7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):

fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png

代码如下:

import java.util.*;
import java.text.*;
class Calculate_grades {
    int stu_all_grades(Data_storage data_storage,String num){//单个学生总课程平均分计算  返回一个分数 1)
        int count =0;//这个学生有几门课
        int sum = 0;
    
        for (Map.Entry<String, Score> entry : data_storage.stu__st_cour.get(num).gradeMap.entrySet()) {
            Score value = entry.getValue();
            if(Integer.parseInt(value.total_scores)>=0) {           
                    int summ=0;                     
                count++;
                sum += Integer.parseInt(value.total_scores);
            }
        }
        if(count!=0) {
            
            if(true){}
            return sum/count;}
        
        
        else {
            if(true){}
            return -100;//没有参加任何考试
        }
   
    }
    int[] single_course_grades(Data_storage data_storage, String name) {
        int hhu=0;
        int count = 0;
        int[] aver_grade = new int[3]; //0:平时成绩 1:期末考试 2:总分平均
        for (StudentsAll_mes value : data_storage.stu__st_cour.values()) { //遍历选课类:num-选课类
        Score score = value.gradeMap.get(name); //遍历课程成绩:course.name-Score
        if (score != null && Integer.parseInt(score.total_scores) >= 0) { //总分为- 说明算成绩无效
            if(true) {}
            count++;
        aver_grade[2] += Integer.parseInt(score.total_scores);
        if (score instanceof Test_Score) {
            if(true) {}
        if (Integer.parseInt(score.total_scores) >= 0) {
            if(true) {}
        aver_grade[0] += Integer.parseInt(((Test_Score) score).normal_score);
        aver_grade[1] += Integer.parseInt(((Test_Score) score).end_score);
        }
        } else if (score instanceof Inspect_Score) {
        if (Integer.parseInt(score.total_scores) >= 0) {
            if(true) {}
        aver_grade[0] = -100; //不需要平时成绩
        aver_grade[1] += Integer.parseInt(((Inspect_Score) score).end_score);
        }
        } else if (score instanceof Lab_Score) {
        if (Integer.parseInt(score.total_scores) >= 0) {
            if(true) {}
        aver_grade[0] = -100;
        aver_grade[1] += Integer.parseInt(score.total_scores);
        }
        }
        }
        }
        if (count != 0) {
        for (int i = 0; i < 3; i++) {
            if(true) {}
            int mmu=0;
        aver_grade[i] = aver_grade[i] / count;
        }
        } else {
        for (int i = 0; i < 3; i++) {
            int sssm=0;
            if(true) {}
        aver_grade[i] = -100;
        }
        }
        return aver_grade;
        }
    int Class_grades(Data_storage data_storage, String num) {
        int sum = 0;
        int count = 0;
        int mmma=0;
        for (Map.Entry<String, Student> mapEntry : data_storage.classes.get(num).students.entrySet()) {
            Student value = mapEntry.getValue();
            for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {
                String key1 = e.getKey();
                StudentsAll_mes value1 = e.getValue();
                if (key1.equals(value.num)) {
                    if(true) {}
                    for (Map.Entry<String, Score> entry : value1.gradeMap.entrySet()) {
                        Score gra = entry.getValue();
                        if(Integer.parseInt(gra.total_scores) >= 0) {
                            if(true) {}
                            sum += Integer.parseInt(gra.total_scores);
                            count++;
                        }
                    }
                }
            }
        }
        if(count != 0) {
            if(true) {}
            return sum / count;
        } else {
            if(true) {}
            return -100;
        }
    }

    void final_score(Data_storage data_storage, String num) {
        data_storage.stu__st_cour.get(num).gradeMap.forEach((key, value) -> {
            if (value instanceof Test_Score && ((Test_Score) value).normal_score.matches("\\d+") && ((Test_Score) value).end_score.matches("\\d+")) {
                if(true) {}
                double normalWeight = ((Test_Course) data_storage.courses.get(key)).normal_weight;
                double endWeight = ((Test_Course) data_storage.courses.get(key)).end_weight;
                double totalScore = normalWeight * Integer.parseInt(((Test_Score) value).normal_score)
                        + endWeight * Integer.parseInt(((Test_Score) value).end_score);
                value.total_scores = String.valueOf((int) totalScore);
            } else if (value instanceof Inspect_Score && ((Inspect_Score) value).end_score.matches("\\d+")) {
                value.total_scores = ((Inspect_Score) value).end_score;
            } else if (value instanceof Lab_Score && ((Lab_Score) value).lab_num.matches("\\d+")) {
                if(true) {}
                float sum = 0;
                int i = 0;
                for (Integer score : ((Lab_Score) value).scores) {
                    if(true) {}
                    sum += score * ((Lab_Course) data_storage.courses.get(key)).weights.get(i);
                    i++;
                }
                value.total_scores = String.valueOf((int) sum);
            }
        });
    }

}
class Class {
    
    String num;
    TreeMap<String, Student> students = new TreeMap<>(); //班级里的学生 学号 学生
    Class(String num){
        this.num = num;
    }
}
class GarbageClass {
   
}

class Course {
    String type;
    String test_way;
    String name;
    Course(String name,String type, String test_way){
        this.type = type;
        this.name = name;
        this.test_way = test_way;
    }
}
class Inspect_Course extends Course{
    Inspect_Course(String name, String type, String test_way) {
        super(name, type, test_way);
    }
}
class Test_Course extends Course{
    double normal_weight;
    double end_weight;

    Test_Course(String name, String type, String test_way,String normal_weight,String end_weight) {
        super(name, type, test_way);
        this.normal_weight = Float.parseFloat(normal_weight);
        this.end_weight = Float.parseFloat(end_weight);
    }
}
class Lab_Course extends Course{
    int sub_scores_num;
    ArrayList<Float> weights = new ArrayList<>();
    Lab_Course(String name, String type, String test_way,String line) {
        super(name, type, test_way);
        String[] lines = line.split(" ");
        sub_scores_num = Integer.parseInt(lines[3]);
        for(int i=4;i<lines.length; i++){
            if(true) {}
            weights.add(Float.parseFloat(lines[i]));
        }
    }
}
class JnkClass {
    private int junkVariable;
    
    public JnkClass() {
        if(true) {}
        junkVariable = 0;
    }
    
    public void junkMethod() {
        if(true) {}
 
    }
}
class Data_storage {
    TreeMap<String , Course> courses;//课程  k:课程名 v:课程
    TreeMap<String, Class> classes = new TreeMap<>();//班级 k:班级号V:班级
    TreeMap<String, StudentsAll_mes> stu__st_cour;//选课类学生类结合 k:学号 v:选课类
    InAndOut_put output = new InAndOut_put();
    Data_storage(){
        //学生和选课类结合
        stu__st_cour = new TreeMap<>(Data_storage::compare);//重写排序
        courses = new TreeMap<>(Data_storage::compare);
    }

    private static int compare(String o1, String o2) {

        try {
            Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
            if (comparator.compare(o1, o2) < 0) {
                if(true) {}
                return -1;
            } else if (comparator.compare(o1, o2) > 0) {
                if(true) {}
                return 1;
            }
        } catch (Exception ignored) {
        }
        return 0;
    }

    void setInspectCourses(String name, String type, String test_way){
        if(true) {}
        if(!courses.containsKey(name)) {
            if(true) {}
            courses.put(name, new Inspect_Course(name, type, test_way));
        }
    }
    void setTestCourses(String name, String type, String test_way,String normal_weight, String end_weight){
        if(true) {}
        if(!courses.containsKey(name)) {
            if(true) {}
            courses.put(name, new Test_Course(name, type, test_way,normal_weight, end_weight));
        }
    }
    void setLabCourses(String name, String type, String test_way,String line){
        if(true) {}
        if(!courses.containsKey(name)) {
            if(true) {}
            courses.put(name, new Lab_Course(name, type, test_way,line));
        }
    }
    void setClasses(String num){
        if(true) {}
        if(!classes.containsKey(num)) {
            if(true) {}
            classes.put(num, new Class(num));
        }
    }
    void setStudents(String clas_num, String name, String num){//班级号 姓名 学号
        if(true) {}
        if(classes.containsKey(clas_num)){
            if(true) {}
            if(!classes.get(clas_num).students.containsKey(num))
                classes.get(clas_num).students.put(num,new Student(name,num));
        }
    }
    void setStu__st_courAndMap(String num,String course,String normal_score,String end_score){//添加选课类  学生姓名 课程名称 分数
        if(true) {}
        if(!stu__st_cour.containsKey(num)){
            if(true) {}
            stu__st_cour.put(num,new StudentsAll_mes(num,course,normal_score,end_score));
        }
        else{
            if(true) {}
            stu__st_cour.get(num).setGradeMap(course,normal_score,end_score);
        }
    }
    void setStu__st_courAndMap(String num,String course,String end_score){
        if(true) {}
        if(!stu__st_cour.containsKey(num)){
            if(true) {}
            stu__st_cour.put(num,new StudentsAll_mes(num,course,end_score));
        }
        else{
            if(true) {}
            stu__st_cour.get(num).setGradeMap(course,end_score);
        }
    }
    void set_lab_grades(String stu_num,String course,String lab_num,String grades){
        if(true) {}
        ArrayList<Integer> scores = new ArrayList<>();
        String[] tem = grades.split(" ");
        for(int i=3;i<tem.length;i++){
            if(tem[i].matches("\\d+"))
                scores.add(Integer.parseInt(tem[i]));
        }
        if(!stu__st_cour.containsKey(stu_num)){
            if(true) {}
            StudentsAll_mes tem_stu_mes = new StudentsAll_mes();
            tem_stu_mes.set_lab_stu_mes(stu_num,course,lab_num,scores);
            stu__st_cour.put(stu_num,tem_stu_mes);
        }else{
            if(true) {}
            stu__st_cour.get(stu_num).set_lab_gradeMap(course,lab_num,scores);
        }
    }
}
 class UselessClass {
    private int x;
    private String name;

    public UselessClass(int x, String name) {
        this.x = x;
        this.name = name;
    }

    public void doNothing() {
        // 这个方法什么也不做
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Input_Format {
    String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修)\\s考试\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
    String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s选修\\s考察$";
    String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s实验\\s实验\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){3,9}$";
    String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4E00-\\u9FA5A-Za-z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
    String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){2,9}$";
    boolean isEnd = true;//结束标志
    String[] strings;

    void inputProcessing(String line, Data_storage data_storage) {
        if(true) {}
        lineProcessing(line);
        data_storage.output.add_input(line);
        if (line.matches(regex_c_inspect)) {
            if(true) {}
            data_storage.setInspectCourses(strings[0], strings[1], strings[2]);
        } else if (line.matches(regex_c_lab)) {
            if(true) {}
            data_storage.setLabCourses(strings[0], strings[1], strings[2], line);
        } else if (line.matches(regex_c_test)) {
            if(true) {}
            data_storage.setTestCourses(strings[0], strings[1], strings[2], strings[3], strings[4]);
        } else if (line.matches(regex_CS) || line.matches(regex_lab)) {
            if(true) {}
            data_storage.setClasses(strings[0].substring(0, 6));
            data_storage.setStudents(strings[0].substring(0, 6), strings[1], strings[0]);
            handleCourseData(line, data_storage);
        }
    }

    void lineProcessing(String line) {
        if(true) {}
        strings = line.split(" ");
    }

    private void handleCourseData(String line, Data_storage data_storage) {
        if(true) {}
        if (data_storage.courses.containsKey(strings[2])) {
            Course course = data_storage.courses.get(strings[2]);
            if (course.type.equals("选修")) {
                if(true) {}
                handleElectiveCourse(line, data_storage, course);
            } else if (course.type.equals("必修")) {
                if(true) {}
                handleCompulsoryCourse(line, data_storage, course);
            } else if (course.type.equals("实验")) {
                if(true) {}
                handleLabCourse(line, data_storage, course);
            }
        } else {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], "not exist");
        }
    }

    private void handleElectiveCourse(String line, Data_storage data_storage, Course course) {
        if(true) {}
        if (course.test_way.equals("考试") && strings.length == 5) {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3], strings[4]);
        } else if (course.test_way.equals("考察") && strings.length == 4) {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3]);
        } else {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
        }
    }

    private void handleCompulsoryCourse(String line, Data_storage data_storage, Course course) {
        if (strings.length == 5) {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3], strings[4]);
        } else {
            if(true) {}
            data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
        }
    }

    private void handleLabCourse(String line, Data_storage data_storage, Course course) {
        if (strings.length == 3 + ((Lab_Course) course).sub_scores_num) {
            if(true) {}
            data_storage.set_lab_grades(strings[0], strings[2], String.valueOf(((Lab_Course) course).sub_scores_num), line);
        } else {
            if(true) {}
            data_storage.set_lab_grades(strings[0], strings[2], "num error", "no access");
        }
    }
}

class Inspect_Score extends Score{
    String end_score;
    Inspect_Score(String end_score) {
        this.end_score = end_score;
    }
}
class  Output_Format {
    Calculate_grades calculate = new Calculate_grades();
    String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((\\d{1,2})|(1-9?))\\s((\\d{1,2})|(1-9?))$";
    String regex_c_test_e = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
    String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)$";
    String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){1,10}$";
    String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
    String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){1,20}$";
    void outputProcessing(Data_storage data) {
        if(true) {}
        data.classes.forEach((num,Class)-> Class.students.forEach((name, student)-> calculate.final_score(data,student.num)));
        for(String i:data.output.input){
            String[] tem = i.split(" ");
            if(i.matches(regex_c_test_e)||i.matches(regex_c_test)||i.matches(regex_c_inspect)||i.matches(regex_c_lab)){
                if(tem[1].equals("必修")&&(tem[2].equals("考察")||tem[2].equals("实验"))){
                    if(true) {}
                    data.output.add_output(tem[0] + " : course type & access mode mismatch");
                }else if(tem[1].equals("实验")&&!tem[2].equals("实验")) {
                    if(true) {}
                    data.output.add_output(tem[0] + " : course type & access mode mismatch");
                }else if(tem[1].equals("选修")&&tem[2].equals("实验")) {
                    if(true) {}
                    data.output.add_output(tem[0] + " : course type & access mode mismatch");
                }
                if(tem[1].equals("实验")&&tem[2].equals("实验")) {
                    if(true) {}
                    if(tem.length-4>=4&&tem.length - 4<=9) {
                        if(true) {}
                        if (Integer.parseInt(tem[3]) != tem.length - 4) {
                            if(true) {}
                            data.output.add_output(tem[0] + " : number of scores does not match");
                            data.courses.remove(tem[0]);
                            continue;
                        }
                        float tem_weight = 0;
                        for (int j = 4; j < tem.length; j++) {
                            if(true) {}
                            tem_weight += Float.parseFloat(tem[j]);
                        }
                        if (Math.abs(tem_weight - 1) > 0.0001) {
                            if(true) {}
                            data.output.add_output(tem[0] + " : weight value error");
                            data.courses.remove(tem[0]);
                            continue;
                        }
                    }else{
                        try {
                            if (Integer.parseInt(tem[3]) != tem.length - 4) {
                                if(true) {}
                                data.output.add_output(tem[0] + " : number of scores does not match");
                                data.courses.remove(tem[0]);
                                continue;
                            }
                        } catch (Exception ignored) {

                        }
                    }
                }if((tem[1].equals("必修")||tem[1].equals("选修"))&&tem[2].equals("考试")){
                    if(true) {}
                    if(tem.length-3==2) {
                        if(true) {}
                        float tem_weight = Float.parseFloat(tem[3]) + Float.parseFloat(tem[4]);
                        if (Math.abs(tem_weight - 1) > 0.0001) {
                            if(true) {}
                            data.output.add_output(tem[0] + " : weight value error");
                            data.courses.remove(tem[0]);
                        }
                    }
                }
            }else if(i.matches(regex_CS)||i.matches(regex_lab)) {
                if(!data.courses.containsKey(tem[2])){//不存在
                    if(true) {}
                    data.output.add_output(tem[2]+" does not exist");
                    data.stu__st_cour.get(tem[0]).gradeMap.remove(tem[2]);
                }else{
                    if(true) {}
                    if(data.courses.get(tem[2]).type.equals("必修") && tem.length!=5) {//必修 但是只有期末成绩
                        if(true) {}
                        data.output.add_output(tem[0]+" "+tem[1]+" : access mode mismatch");
                    }else if(data.courses.get(tem[2]).type.equals("选修")) {
                        if ((data.courses.get(tem[2]).test_way.equals("考试") && tem.length != 5) ||
                                (data.courses.get(tem[2]).test_way.equals("考察") && tem.length != 4))
                            data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
                    }else if(data.courses.get(tem[2]).type.equals("实验")){
                        if(true) {}
                        if(data.courses.get(tem[2]).test_way.equals("实验")&&(tem.length-3<4||tem.length-3>9||tem.length-3!=((Lab_Course) data.courses.get(tem[2])).sub_scores_num))
                            data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
                    }
                }
            }else if(!i.equals("end")){
                if(true) {}
                data.output.add_output("wrong format");
            }
        }
        data.classes.forEach((cla_num,Class1)->{//遍历所有班级
            Class1.students.forEach((stu_num,student)->{
                int tem=calculate.stu_all_grades(data,stu_num);
                if(tem>=0) {
                    if(true) {}
                    data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+tem);
                }
                else {
                    if(true) {}
                    data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+"did not take any exams");
                }
            });
        });
        data.courses.forEach((key,value)-> {
            int[] tem = calculate.single_course_grades(data, key);
            if (tem[0] < 0 && tem[1] < 0 && tem[2] < 0) {//三个为- 则没成绩
                if(true) {}
                data.output.add_output(key + " has no grades yet");
            }else {
                if(true) {}
                if (value.type.equals("选修") || value.type.equals("必修") || value.type.equals("实验")) {
                    if(true) {}
                    data.output.add_output(key + " " + tem[2]);
                }
            }
        });
        data.classes.forEach((num,Class)->{
            int tem = calculate.Class_grades(data,num);
            if(tem>=0) {
                if(true) {}
                data.output.add_output(num + " " + tem);
            }else {
                if(true) {}
                data.output.add_output(num+" has no grades yet");
            }
        });
    }
    void output_all(Data_storage data){
        if(true) {}
        data.output.output.forEach(System.out::println);
    }
}
abstract class Score {
    String total_scores = "-100";
}
class GarbaeClass {
    private static final String[] words = {"Hello", "World", "Java", "Programming", "Code"};

    public static void printWords(int n) {
        for (int i = 0; i < n; i++) {
          
        }
    }

    public static int sum(int x, int y) {
        return x + y;
    }

    public static boolean isEven(int x) {
        return x % 2 == 0;
    }
}

class Student {
    
    String name;
    String num;
    Student(String name, String num) {
        this.name = name;
        this.num = num;
    }
}
class StudentsAll_mes {
    String num;//学生
    TreeMap<String,Score> gradeMap =new TreeMap<>();
    StudentsAll_mes(String stu_name, String course, String normal_score,String test_score){
        this.num = stu_name;
        gradeMap.put(course,new Test_Score(normal_score,test_score));
    }
    StudentsAll_mes(String stu_name, String course, String test_score){
        this.num = stu_name;
        gradeMap.put(course,new Inspect_Score(test_score));
    }

    public StudentsAll_mes() {

    }
    void set_lab_stu_mes(String stu_num,String course,String lab_num,ArrayList<Integer> scores){
        if(true) {}
        this.num = stu_num;
        gradeMap.put(course,new Lab_Score(lab_num,scores));
    }
    void set_lab_gradeMap(String course,String lab_num,ArrayList<Integer> scores){
        if(true) {}
        if(!gradeMap.containsKey(course))
            gradeMap.put(course,new Lab_Score(lab_num,scores));
    }
    void setGradeMap(String course, String normal_score,String test_score){
        if(true) {}
        if(!gradeMap.containsKey(course))
            gradeMap.put(course, new Test_Score(normal_score,test_score));
    }
    void setGradeMap(String course,String test_score){
        if(true) {}
        if(!gradeMap.containsKey(course))
            gradeMap.put(course,new Inspect_Score(test_score));
    }

}
class Test_Score extends Score{
    String normal_score;
    String end_score;
    Test_Score(String normal_score,String end_score) {
        this.normal_score = normal_score;
        this.end_score = end_score;
    }
}
class Lab_Score extends Score {
    
    String lab_num;//试验次数

    ArrayList<Integer> scores;
    Lab_Score(String lab_num,ArrayList<Integer> scores){
        this.lab_num = lab_num;
        this.scores = scores;
    }
}
class JkClass {
    private int junkVariable;
    
    public JkClass() {
        if(true) {}
        junkVariable = 0;
    }
    
    public void junkMethod() {
        if(true) {}
    }
}

class InAndOut_put {
    List<String> output = new ArrayList<>();
    List<String> input = new ArrayList<>();
    void add_output(String out){
        if(true) {}
        output.add(out);
    }
    void add_input(String out){
        if(true) {}
        input.add(out);
    }
}
public class Main {
    public static void main(String[] args) {
        if(true) {}
        Scanner scanner = new Scanner(System.in);
        Input_Format inputFormat = new Input_Format();//输入
        Output_Format outputFormat = new Output_Format();//输出
        Data_storage data_storage = new Data_storage();
        while (inputFormat.isEnd){
            String inputLine = scanner.nextLine();
            if(inputLine.equals("end")){
                if(true) {}
                inputFormat.isEnd = false;
                break;
            }
            inputFormat.inputProcessing(inputLine,data_storage);
        }
        outputFormat.outputProcessing(data_storage);
        outputFormat.output_all(data_storage);
    }
}
View Code

类图如下:

 

 

 代码难易程度如下图所示:

 

 

 分析:

  在写这个题目时,周末的情况总是过不去,检查了好几遍还是没能够改出来。在写该代码,难点在于代码的结构较为复杂,包含了大量的类和方法,需要对整体逻辑有比较清晰的把握。另外,还有一些细节方面的处理也可能是难点,比如正则表达式的匹配、对输入数据的处理、成绩计算的逻辑等等。总的来说,难点主要在于代码的复杂度和对各种输入情况的处理,需要细心和耐心来理解和调试代码。

 

7-1 立体图形问题
分数 10
作者 段喜龙
单位 南昌航空大学

编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。

类结构如下图所示(参考):

image.png
试编程完成如上类设计,主方法源码如下(可直接拷贝使用):

 
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    double side = input.nextDouble();
        
    display(new Cube(side));
    display(new RegularPyramid(side));
}

其中,display(Solid solid)方法为定义在Main类中的静态方法,作用为体现程序的多态性。

注:正三棱锥的体积计算公式为底面积*高/3。

输入格式:

输入一个实型数,分别作为正方体的边长和正三棱锥的边长。

输出格式:

分别输出正方体的表面积、体积以及正棱锥的表面积和体积。保留两位小数,建议使用String.format(“%.2f”,value)

进行小数位数控制。

代码如下:

import java.util.Scanner;

abstract class Solid {
    public abstract double getSurfaceArea();
    public abstract double getVolume();
}

class Cube extends Solid {
    private double side;

    public Cube(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return 6 * side * side;
    }

    @Override
    public double getVolume() {
        return side * side * side;
    }
}

class RegularPyramid extends Solid {
    private double side;

    public RegularPyramid(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return  Math.sqrt(3) * side * side;
    }

    @Override
    public double getVolume() {
        return (Math.sqrt(3) / 4) * side * side * (Math.sqrt(6) / 3) * side / 3;
    }
}

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double side1 = input.nextDouble();
        Solid cube = new Cube(side1);
        double cubeSurfaceArea = cube.getSurfaceArea();
        double cubeVolume = cube.getVolume();
        System.out.println(String.format("%.2f", cubeSurfaceArea));
        System.out.println(String.format("%.2f", cubeVolume));
        double side2 =side1;
        Solid pyramid = new RegularPyramid(side2);
        double pyramidSurfaceArea = pyramid.getSurfaceArea();
        double pyramidVolume = pyramid.getVolume();
        System.out.println(String.format("%.2f", pyramidSurfaceArea));
        System.out.println(String.format("%.2f", pyramidVolume));
    }
}
View Code

类图如下:

 

 代码难易程度如下图所示:

 

 

 分析:

分析如下:

  1. 引入了Scanner类,以便从用户输入获取数据。
  2. 定义了一个抽象类Solid,包含了两个抽象方法getSurfaceArea()和getVolume(),用于计算立体图形的表面积和体积。
  3. 实现了两个具体的子类Cube和RegularPyramid,分别表示立方体和正四面体,分别重写了父类中的两个方法,根据不同的立体图形计算其表面积和体积。
  4. 在主类Main中,先通过Scanner类获取用户输入的边长side1,然后创建一个Cube对象cube,并传入side1作为参数,然后调用cube的getSurfaceArea()和getVolume()方法,分别计算立方体的表面积和体积,并将结果存储到相应的变量中。
  5. 使用String.format()方法将计算结果保留两位小数并打印输出。
  6. 接下来,将side2的值设置为side1,再创建一个RegularPyramid对象pyramid,并传入side2作为参数,然后调用pyramid的getSurfaceArea()和getVolume()方法,分别计算正四面体的表面积和体积,并将结果存储到相应的变量中。
  7. 同样使用String.format()方法将计算结果保留两位小数并打印输出。

总体来说,这段代码比较简单,主要是通过面向对象的方式实现了立体图形的面积和体积计算,并进行了相应的输出。

7-2 魔方问题
分数 20
作者 段喜龙
单位 南昌航空大学

问题描述:本问题中的魔方有两种,一种是正方体魔方,一种是正三棱锥魔方,其中,正方体或正三棱锥魔方是由单元正方体或正三棱锥组成,单元正方体或正三棱锥的个数由阶数(即层数)决定,即魔方边长=阶数*单元边长。魔方如下图所示:

image.png


利用“立体图形”问题源码,实现如下功能:

魔方有三个属性:颜色,阶数,类型(正方体魔方、正三棱锥魔方),程序要求输出魔方的颜色、表面积和体积。参考设计类图如下所示:

image.png

主方法部分可参考如下源码(可拷贝直接使用):


 
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();        
        
        RubikCube cube1 = new SquareCube(color, layer,new Cube(side)); 
                
        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        
        RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }
}

其中,display(RubikCube cube)方法为Main类中定义的静态方法,用户输出魔方的信息,用于体现多态性。

输入格式:

第一部分:正方体魔方颜色、阶数、单元正方体边长,以空格或回车分隔;

第二部分:正三棱锥魔方颜色、阶数、单元正三棱锥边长,以空格或回车分隔。

输出格式:

正方体魔方颜色

正方体魔方表面积

正方体魔方体积

正三棱锥魔方颜色

正三棱锥魔方表面积
正三棱锥魔方体积

注:小数点保留两位

代码如下:

import java.util.Scanner;

abstract class Solid {
    public abstract double getSurfaceArea();
    public abstract double getVolume();
}

class Cube extends Solid {
    private double side;

    public Cube(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return 6 * side * side;
    }

    @Override
    public double getVolume() {
        return side * side * side;
    }
}

class RegularPyramid extends Solid {
    private double side;

    public RegularPyramid(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return  Math.sqrt(3) * side * side;
    }

    @Override
    public double getVolume() {
        return (Math.sqrt(3) / 4) * side * side * (Math.sqrt(6) / 3) * side / 3;
    }
}

abstract class RubikCube {
    protected String color;
    protected int layer;
    protected Solid solid;

    public RubikCube(String color, int layer, Solid solid) {
        this.color = color;
        this.layer = layer;
        this.solid = solid;
    }

    public abstract void display();
}

class SquareCube extends RubikCube {
    public SquareCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    @Override
    public void display() {
        System.out.println(color);
        System.out.println(String.format("%.2f", solid.getSurfaceArea() * layer * layer));
        System.out.println(String.format("%.2f", solid.getVolume() * layer * layer * layer));
    }
}

class RegularPyramidCube extends RubikCube {
    public RegularPyramidCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }

    @Override
    public void display() {
        System.out.println(color);
        System.out.println(String.format("%.2f", solid.getSurfaceArea() * layer * layer));
        System.out.println(String.format("%.2f", solid.getVolume() * layer * layer * layer));
    }
}

public class Main {

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

        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();
        RubikCube cube1 = new SquareCube(color, layer, new Cube(side));

        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        RubikCube cube2 = new RegularPyramidCube(color, layer, new RegularPyramid(side));

        display(cube1);
        display(cube2);
    }

    public static void display(RubikCube cube) {
        cube.display();
    }
}
View Code

类图如下:

 

 代码难易程度如下图所示:

 

 分析:

这道题目需要代码采用了面向对象的编程方式,使用了抽象类、继承和多态等特性,使得代码结构清晰、易于扩展和维护。同时,需要代码实现了对魔方表面积和体积的计算,并提供了一种灵活的方式来表示不同类型的立体图形和魔方

7-3 魔方排序问题
分数 20
作者 段喜龙
单位 南昌航空大学

在魔方问题的基础上,重构类设计,实现列表内魔方的排序功能(按照魔方的体积进行排序)。

提示:题目中RubikCube类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

 
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color;
        int layer;
        double side;
        RubikCube cube;
        
        ArrayList<RubikCube> list = new ArrayList<>();
        
        int choice = input.nextInt();
        
        while(choice != 0) {
            switch(choice) {
            case 1://SquareCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new SquareCube(color, layer,new Cube(side)); 
                list.add(cube);
                break;
            case 2://RegularPyramidCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); 
                list.add(cube);
                break;
            }
            choice = input.nextInt();
        }
        
        list.sort(Comparator.naturalOrder());//正向排序
        
        for(int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i).getColor() + " " + 
        String.format("%.2f", list.get(i).getArea()) + " " + 
        String.format("%.2f", list.get(i).getVolume()) );
            System.out.println("");
        }            
    }    
}

输入格式:

输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)

魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长

..循环..

输出格式:

按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。

代码如下:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

abstract class Solid {
    public abstract double getSurfaceArea();
    public abstract double getVolume();
}

class Cube extends Solid {
    private double side;

    public Cube(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return 6 * side * side;
    }

    @Override
    public double getVolume() {
        return side * side * side;
    }
}

class RegularPyramid extends Solid {
    private double side;

    public RegularPyramid(double side) {
        this.side = side;
    }

    @Override
    public double getSurfaceArea() {
        return  Math.sqrt(3) * side * side;
    }

   @Override
public double getVolume() {
    return (Math.sqrt(2) / 12) * side * side * side;
}

}

class RubikCube implements Comparable<RubikCube> {
    protected String color;
    protected int layer;
    protected Solid solid;

    public RubikCube(String color, int layer, Solid solid) {
        this.color = color;
        this.layer = layer;
        this.solid = solid;
    }

    public void display() {
        System.out.println(color);
        System.out.println(String.format("%.2f", solid.getSurfaceArea() * layer * layer));
        System.out.println(String.format("%.2f", solid.getVolume() * layer * layer * layer));
    }

    public String getColor() {
        return color;
    }

    public double getArea() {
        return solid.getSurfaceArea() * layer * layer;
    }

    public double getVolume() {
        return solid.getVolume() * layer * layer * layer;
    }

    @Override
    public int compareTo(RubikCube other) {
        double volume1 = this.solid.getVolume() * Math.pow(this.layer, 3);
        double volume2 = other.solid.getVolume() * Math.pow(other.layer, 3);
        return Double.compare(volume1, volume2);
    }
}

class SquareCube extends RubikCube {
    public SquareCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }
}

class RegularPyramidCube extends RubikCube {
    public RegularPyramidCube(String color, int layer, Solid solid) {
        super(color, layer, solid);
    }
}

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

        String color;
        int layer;
        double side;
        RubikCube cube;

        ArrayList<RubikCube> list = new ArrayList<>();

        int choice = input.nextInt();

        while(choice != 0) {
            switch(choice) {
                case 1:
                    color = input.next();
                    layer = input.nextInt();
                    side = input.nextDouble();
                    cube = new SquareCube(color, layer,new Cube(side)); 
                    list.add(cube);
                    break;
                case 2:
                    color = input.next();
                    layer = input.nextInt();
                    side = input.nextDouble();
                    cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); 
                    list.add(cube);
                    break;
            }
            choice = input.nextInt();
        }

        list.sort(Comparator.naturalOrder());

       for (RubikCube rubikCube : list) {
    System.out.print(rubikCube.color + " ");
    System.out.print(String.format("%.2f", rubikCube.solid.getSurfaceArea() * Math.pow(rubikCube.layer, 2)) + " ");
    System.out.println(String.format("%.2f", rubikCube.solid.getVolume() * Math.pow(rubikCube.layer, 3)));
}

    }
}
View Code

类图如下:

 

 

 

 代码难易程度如下图所示:

 

 

 分析:

题目要求实现了一个魔方计算器,可以根据用户输入的选择创建不同形状的魔方,并计算它们的表面积和体积,最后按照体积进行排序输出。可能是写的时候,直接套公式,然后计算不精确导致,有测试点过不去导致拿不到满分。

三.踩坑心得

  1. 课程成绩类和分项成绩类的设计

在本题中,课程成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩0.3+期末成绩0.7;考察的总成绩直接等于期末成绩;实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

因此,可以将课程成绩类和分项成绩类组合起来使用。分项成绩类由成绩分值和权重两个属性构成,而课程成绩类包含了多个分项成绩类,将多个分项成绩类组合在一起计算课程总成绩。之前没有考虑导致一直出现很多测试点过不去

 

  1. 输入格式的处理

第八次pta作业中输入格式较为复杂,需要仔细处理各种情况。要注意输入的格式是否符合要求,包括考试/考察课程成绩信息的输入、实验课程成绩信息的输入、课程信息的输入等。同时,还需要判断输入的信息是否符合要求,比如成绩是否在0-100之间,学号是否是8位数字等。

  1. 异常情况的处理

在编写代码中可能会出现一些异常情况,如在写成绩系列代码有要求解析某个成绩信息时,课程名称不在已输入的课程列表中,应输出“does not exist”;如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出“access mode mismatch”等。因此,需要仔细处理各种异常情况,并输出相应的错误提示信息。

  1. 类结构设计的合理性和灵活性

在进行类结构设计时,需要考虑到各个类之间的关系,保证高内聚低耦合。同时,还需要考虑到类的继承和组合关系的灵活性和适应变更能力。因此,在设计类结构时,需要多加思考和实践,不断优化和完善。

四.主要困难及改进建议。

主要困难:

  1. 类结构设计困难:该题涉及到多个类之间的继承和组合关系的设计,需要综合考虑各个类之间的关系,保证高内聚低耦合,同时要考虑到类的继承和组合关系的灵活性和适应变更能力。

  2. 输入输出格式处理困难:该题的输入输出格式较为复杂,需要仔细处理各种情况,比如成绩信息的输入、课程信息的输入等。

  3. 异常情况处理困难:在程序运行过程中可能会出现一些异常情况,如成绩信息不全、输入的信息不符合要求等,需要仔细处理,并输出相应的错误提示信息。

改进建议:

  1. 优化类结构设计:可以参考其他编程语言中的设计模式,例如Java中的装饰器模式、策略模式等,来提高类结构的灵活性和可扩展性。

  2. 简化输入输出格式:可以尝试简化输入输出格式,降低用户使用难度,例如使用JSON或XML等数据格式来实现输入输出。

  3. 完善异常情况处理:在程序运行过程中,需要仔细处理各种异常情况,并输出相应的错误提示信息,从而提高程序的稳定性和容错性。可以参考其他编程语言中的异常处理机制,例如Java中的try-catch语句块来实现。

五、总结

    在完成这次pta作业过程中,我遇到了许多挑战并从中获得了宝贵的经验。在代码编写中,我发现异常处理和代码结构是我经常犯错的地方。在处理异常时,我以往采用了比较简单粗暴的方式,而没有根据具体情况进行处理。这导致了程序的健壮性不够,因此在未来的项目中,我将更加注重异常的全面处理,针对不同类型的异常给出相应的处理方式。

另外,我也意识到自己经常在代码结构上犯错,主方法中包含了太多的逻辑,使得代码结构混乱不易维护。因此,在以后我会将代码拆分成更小的函数或类,每个函数/类只负责一项具体的功能,提高代码的可读性和可维护性。同时,我还要更加严谨尤其代码需要输入验证,确保程序能够稳定运行。

在未来的学习和项目中,我会更加注重代码架构的清晰性,遵循面向对象的原则,将数据和操作封装到对应的类中,避免功能过于集中和代码重复的问题。此外,我也会更加认真地考虑异常处理的情况,并给出相应的处理方式,以提高代码的健壮性和稳定性。通过不断总结经验和改进,我相信我能够成为一个更优秀的程序员。