第三次博客作业

前言

这是第三次博客作业,总结了近三次PTA大作业的完成情况,作业7、8次的大作业的小题目围绕着HashMap、ArrayList和自定义接口来展开,大题目则是课程成绩程序的第二次第三次迭代,因为第一次课程成绩的程序写的结构不太好,于是重新写的,第三次迭代并没有拿到满分,后面也没有时间改了。期末考试则是由29个选择题和四个编程题组成。

关于类和整个程序的设计:

类是面向对象编程中的核心概念,通过类可以定义一组数据和与之相关的操作。在设计程序时,通常需要先考虑需要哪些对象和它们的属性和行为,然后将这些信息组织成类的结构。在类的设计中,需要考虑类的名称、属性、方法、访问权限等方面。

除了类的设计,程序的整体设计也非常重要。程序的整体设计涉及到程序的架构、模块划分、代码组织方式、代码风格等方面。程序的整体设计需要遵循一些基本原则,如低耦合、高内聚、模块化等,以确保程序的可维护性、扩展性和可重用性。

在设计程序时,还需要考虑程序的性能、安全性、可靠性等方面。这些方面的考虑需要在程序开发的不同阶段进行,例如在编码阶段需要考虑程序的性能优化,而在测试阶段需要考虑程序的安全性和可靠性。

三次题目集的知识点、题量、难度等情况:

(对于重难点题目将会给出完整题目)

第七次大作业:

容器-HashMap:

HashMap是Java中常用的容器类之一,它实现了Map接口,用于存储键值对。下面是HashMap的用法:

  1. 创建HashMap对象:

    HashMap<Key类型, Value类型> hashMap = new HashMap<>();
    
  2. 添加元素:

    hashMap.put(key, value);
    
  3. 获取元素:

    Value value = hashMap.get(key);
    
  4. 删除元素:

    hashMap.remove(key);
    
  5. 判断键是否存在:

    boolean containsKey = hashMap.containsKey(key);
    
  6. 判断值是否存在:

    boolean containsValue = hashMap.containsValue(value);
    
  7. 获取HashMap的大小:

    int size = hashMap.size();
    
  8. 遍历HashMap:

    // 遍历键
    for (Key key : hashMap.keySet()) {
        // 根据键获取值
        Value value = hashMap.get(key);
        // 处理值
    }
    
    // 遍历值
    for (Value value : hashMap.values()) {
        // 处理值
    }
    
    // 遍历键值对
    for (Map.Entry<Key, Value> entry : hashMap.entrySet()) {
        Key key = entry.getKey();
        Value value = entry.getValue();
        // 处理键值对
    }
    

需要注意的是,HashMap中的键是唯一的,如果重复添加相同的键,后面的值会替代前面的值;值可以重复。此外,HashMap是无序的,元素的顺序不保证一致。

除了基本的用法,还可以使用其他方法和构造函数来满足不同的需求,例如通过构造函数指定初始容量和负载因子,使用putAll()方法将另一个Map中的元素添加到当前HashMap中,使用isEmpty()方法判断HashMap是否为空等。

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

课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃

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

 

第八次大作业:

容器-ArrayList:

ArrayList是Java中常用的动态数组类,它实现了List接口,用于存储一组有序的元素。下面是ArrayList的用法:

  1. 创建ArrayList对象:

    ArrayList<ElementType> arrayList = new ArrayList<>();
    
  2. 添加元素:

    arrayList.add(element);
    

    元素将会被添加到ArrayList的尾部。

  3. 获取元素:

    ElementType element = arrayList.get(index);
    

    使用索引位置来获取ArrayList中指定位置的元素,索引从0开始。

  4. 修改元素:

    arrayList.set(index, newElement);
    

    使用索引位置来替换ArrayList中指定位置的元素。

  5. 删除元素:

    arrayList.remove(index);
    

    使用索引位置来删除ArrayList中指定位置的元素。

  6. 判断元素是否存在:

    boolean containsElement = arrayList.contains(element);
    

    使用contains()方法来判断ArrayList中是否包含指定元素。

  7. 获取ArrayList的大小:

    int size = arrayList.size();
    

    使用size()方法来获取ArrayList的大小。

  8. 遍历ArrayList:

    for (ElementType element : arrayList) {
        // 处理元素
    }
    

需要注意的是,ArrayList可以存储任意类型的元素,包括基本类型的包装类和自定义类型。ArrayList的容量会根据需要进行自动扩容,以适应元素的添加。

除了上述基本用法,ArrayList还提供了许多其他方法,如addAll()方法可以将另一个集合中的元素添加到当前ArrayList中,使用isEmpty()方法判断ArrayList是否为空,使用clear()方法清空ArrayList中的所有元素等。

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

课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃

期末考试:

(这里只分析编程题)

前三题均为关于正方形、正三棱锥及其魔方的迭代问题:

在魔方问题的基础上,

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

提示:题目中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:结束输入)

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

..循环..

输出格式:

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

输入样例:

在这里给出一组输入。例如:

1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0

输出样例:

在这里给出相应的输出。例如:

red 122.21 69.85
yellow 793.50 1520.88
blue 1093.50 2460.38
black 2459.14 6304.73
white 2843.39 10316.38

7-4 销售步枪问题(附加题)

前亚利桑那州境内的一位步枪销售商销售密苏里州制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是销售商在一个月内可销售70个枪机、80个枪托和90个枪管。

根据每个月的销售情况,计算销售商的佣金(提成)算法如下:

  • 不到(含)1000美元的部分为10%;

  • 1000(含)~1800美元的部分为15%;

  • 超过1800美元的部分为20%。

佣金程序生成月份销售报告,汇总销售商的销售总额和佣金。

编程要求:必须符合面向对象编程,且保证类设计的单一职责模式,使用面向过程编程判定0分。

提示:可以设置一个销售订单类。参考类图如下:

输入格式:输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。

输出格式:分别输出销售商在该月的销售额和佣金,中间用空格分开。

输入样例1:

在这里给出一组输入。例如:30 40 50

输出样例1:

在这里给出相应的输出。例如:3800.00 620.00

输入样例2:
在这里给出一组输入。例如:88 56 98

输出样例2:
在这里给出相应的输出。例如:Wrong Format

设计与分析与主要问题和其解决方法

(这里只会提供重点题目的代码)

第七次大作业:

课程成绩2:

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.text.Collator;
  5 import java.util.*;
  6 import java.util.Comparator;
  7 import java.util.Locale;
  8 import java.util.regex.PatternSyntaxException;
  9 import java.util.stream.Collectors;
 10 import java.util.stream.IntStream;
 11 import java.util.List;
 12 import java.util.ArrayList;
 13 
 14 
 15 public class Main {
 16     public static void main(String[] args) {
 17     try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) {
 18         MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint();
 19         messageGetAndPrint.print = new Print();
 20         
 21         in.lines().takeWhile(line -> !line.equals("end")).forEach(messageGetAndPrint::getMessage);
 22         
 23         messageGetAndPrint.print.personPrint(messageGetAndPrint.students, messageGetAndPrint.courseSelections);
 24         messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses, messageGetAndPrint.courseSelections);
 25         messageGetAndPrint.print.classPrint(messageGetAndPrint.classes, messageGetAndPrint.courseSelections);
 26     } catch (IOException e) {
 27         e.printStackTrace();
 28     }
 29 }
 30 }
 31 class Class {
 32     private String classNum;
 33     HashMap<String , Student> students;
 34     Class(String classNum) {
 35         setClassNum(classNum);
 36     }
 37     public void setClassNum(String classNum) {
 38         this.classNum = classNum;
 39     }
 40     public String getClassNum() {
 41         return classNum;
 42     }
 43     public void addStudent(Student student) {
 44         students.put(student.getStudentNum() , student);
 45     }
 46 }
 47 class Student {
 48     private String name;
 49     private String studentNum;
 50     Student(String name , String studentNum) {
 51         setName(name);
 52         setStudentNum(studentNum);
 53     }
 54     public String getName() {
 55         return name;
 56     }
 57     public void setName(String name) {
 58         this.name = name;
 59     }
 60     public String getStudentNum() {
 61         return studentNum;
 62     }
 63     public void setStudentNum(String studentNum) {
 64         this.studentNum = studentNum;
 65     }
 66 }
 67 class Course {
 68     private String className;
 69     private int classQuality;
 70     private int assessmentMethodology;
 71     Course(String className , int classQuality , int assessmentMethodology) {
 72         setClassName(className);
 73         setClassQuality(classQuality);
 74         setAssessmentMethodology(assessmentMethodology);
 75     }
 76     public String getClassName() {
 77         return className;
 78     }
 79     public void setClassName(String className) {
 80         this.className = className;
 81     }
 82     public int getClassQuality() {
 83         return classQuality;
 84     }
 85     public void setClassQuality(int classQuality) {
 86         this.classQuality = classQuality;
 87     }
 88     public int getAssessmentMethodology() {
 89         return assessmentMethodology;
 90     }
 91     public void setAssessmentMethodology(int assessmentMethodology) {
 92         this.assessmentMethodology = assessmentMethodology;
 93     }
 94 }
 95 class CourseSelection {
 96     Student student;
 97     Course course;
 98     Grade grade;
 99 }
100 abstract class Grade {
101     int allGrade;
102     abstract void getAllGrade();
103 }
104 class GradeA extends Grade {//考试
105     private int finalGrade;
106     private int usualGrade;
107     GradeA(int finalGrade , int usualGrade) {
108         setFinalGrade(finalGrade);
109         setUsualGrade(usualGrade);
110     }
111     public void setFinalGrade(int finalGrade) {
112         this.finalGrade = finalGrade;
113     }
114     public int getFinalGrade() {
115         return finalGrade;
116     }
117     public void setUsualGrade(int usualGrade) {
118         this.usualGrade = usualGrade;
119     }
120     public int getUsualGrade() {
121         return usualGrade;
122     }
123     @Override
124     void getAllGrade() {
125         allGrade = (int) (finalGrade*0.7+usualGrade*0.3);
126     }
127 }
128 class GradeB extends Grade {//考察
129     private int finalGrade;
130     GradeB(int finalGrade) {
131         setFinalGrade(finalGrade);
132     }
133     public void setFinalGrade(int finalGrade) {
134         this.finalGrade = finalGrade;
135     }
136     public int getFinalGrade() {
137         return finalGrade;
138     }
139     @Override
140     void getAllGrade() {
141         allGrade = finalGrade;
142     }
143 }
144 class GradeC extends Grade {//实验
145     ArrayList<Integer> usualGrades;
146     GradeC(ArrayList<Integer> usualGrades) {
147         this.usualGrades = usualGrades;
148     }
149     @Override
150     void getAllGrade() {
151         allGrade = 0;
152         for(int x:usualGrades){
153             allGrade+=x;
154         }
155         allGrade = allGrade/usualGrades.size();
156     }
157 }
158 class Print {
159     public void personPrint(HashMap<String , Student> students, ArrayList<CourseSelection> courseSelections) {
160         students.keySet().stream()
161                 .sorted()
162                 .forEach(key -> {
163                     Student student = students.get(key); // 获取当前学生信息
164                     int[] gradeData = courseSelections.stream()
165                             .filter(cs -> cs.student.getStudentNum().equals(student.getStudentNum()))
166                             .mapToInt(cs -> {
167                                 cs.grade.getAllGrade(); // 更新成绩状态
168                                 return cs.grade.allGrade; // 提取当前的总成绩
169                             })
170                             .toArray();
171                     if (gradeData.length == 0) { // 没有成绩数据
172                         System.out.println(student.getStudentNum() + " " + student.getName() + " did not take any exams");
173                     } else {
174                         // 计算平均分并打印
175                         int averageGrade = Arrays.stream(gradeData).sum() / gradeData.length;
176                         System.out.println(student.getStudentNum() + " " + student.getName() + " " + averageGrade);
177                     }
178                 });
179     }
180     public void coursePrint(HashMap<String, Course> courses, ArrayList<CourseSelection> courseSelections) {
181         courses.keySet().stream()
182                 .sorted(new SoftName())
183                 .forEach(key -> {
184                     Course course = courses.get(key);
185                     // 根据课程筛选相关的选课记录
186                     List<CourseSelection> selected = new ArrayList<>();
187 for (CourseSelection cs : courseSelections) {
188     if (cs.course.getClassName().equals(course.getClassName())) {
189         selected.add(cs);
190     }
191 }
192 
193                     if (selected.isEmpty()) {
194                         System.out.println(course.getClassName() + " has no grades yet");
195                         return;
196                     }
197                     // 计算总分和平均分
198                     double allGradesSum = 0;
199                     double finalGradeSum = 0;
200                     double usualGradeSum = 0;
201                     int gradesCount = 0;
202                     int usualGradesCount = 0;
203 
204                     for (CourseSelection cs : selected) {
205                         cs.grade.getAllGrade();
206                         allGradesSum += cs.grade.allGrade;
207                         if (cs.grade instanceof GradeA) {
208                             finalGradeSum += ((GradeA) cs.grade).getFinalGrade(); // Final grade for GradeA
209                             usualGradeSum += ((GradeA) cs.grade).getUsualGrade(); // Usual grade for GradeA
210                             usualGradesCount++;
211                         } else if (cs.grade instanceof GradeB) {
212                             finalGradeSum += ((GradeB) cs.grade).getFinalGrade(); // Final grade for GradeB
213                         }
214                         gradesCount++;
215                     }
216                     double average = gradesCount > 0 ? allGradesSum / gradesCount : 0;
217                     double averageFinal = gradesCount > 0 ? finalGradeSum / gradesCount : 0;
218                     double averageUsual = usualGradesCount > 0 ? usualGradeSum / usualGradesCount : 0;
219                     String output;
220                     if (course.getAssessmentMethodology() == 3) {
221                         output = String.format("%s %d", course.getClassName(), (int) average);
222                     } else if (usualGradesCount == 0) {
223                         output = String.format("%s %d %d", course.getClassName(), (int) averageFinal, (int) average);
224                     } else {
225                         output = String.format("%s %d %d %d", course.getClassName(), (int) averageUsual, (int) averageFinal, (int) average);
226                     }
227                     System.out.println(output);
228                 });
229     }
230     public void classPrint(HashMap<String, Class> classes, ArrayList<CourseSelection> courseSelections) {
231         classes.keySet().stream().sorted().forEach(classKey -> {
232             Class c = classes.get(classKey);
233             double average = courseSelections.stream()
234                     .filter(cs -> c.students.containsKey(cs.student.getStudentNum()))
235                     .mapToInt(cs -> cs.grade.allGrade)
236                     .average()
237                     .orElse(-1);  // 使用 -1 来表示没有成绩的情况
238 
239             String output = average == -1 ?
240                     c.getClassNum() + " has no grades yet" :
241                     c.getClassNum() + " " + (int) average;
242 
243             System.out.println(output);
244         });
245     }
246     public void wrongFormat() {
247         System.out.println("wrong format");
248     }
249     public void course_not_Exist(String name) {
250         System.out.println(name+" does not exist");
251     }
252     public void course_not_Match(String studentNum , String studentName) {
253         System.out.println(studentNum+" "+studentName+" : access mode mismatch");
254     }
255     public void course_not_Match(String name) {
256         System.out.println(name+" : course type & access mode mismatch");
257     }
258     static class SoftName implements Comparator<String> {
259         private static final Comparator<Object> localeComparator = Collator.getInstance(Locale.CHINA);
260         @Override
261         public int compare(String name1 , String name2) {
262             return localeComparator.compare(name1, name2);
263         }
264     }
265 }
266 class MessageGetAndPrint {
267     Print print;
268     HashMap<String , Class> classes = new HashMap<>();
269     HashMap<String , Student> students = new HashMap<>();
270     HashMap<String , Course> courses = new HashMap<>();
271     ArrayList<CourseSelection> courseSelections = new ArrayList<>();
272     public void getMessage(String getInput) {
273         String[] input = getInput.split(" ");
274         try {
275             if (input.length == 2 && input[1].equals("必修")) {
276                 String courseName = input[0];
277                 if(!courses.containsKey(courseName)) {
278                     int i = 1, j = 1; // 保留原代码中的变量和逻辑
279                     Course course = new Course(courseName, i, j);
280                     courses.put(courseName, course);
281                 }
282             }
283         } catch (PatternSyntaxException e) {
284             // 此处可以处理正则表达式的语法错误,但按照题设这里应该没有异常发生,
285             // 所以可以忽略。
286         }
287         if(getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$")) {
288             String[] courseTypes = {"", "必修", "选修", "实验"};
289             String[] examTypes = {"", "考试", "考察", "实验"};
290             int courseTypeIndex = -1, examTypeIndex = -1;
291             for (int k = 1; k <= 3; k++) {
292                 if (input[1].equals(courseTypes[k])) {
293                     courseTypeIndex = k;
294                     break;
295                 }
296             }
297             for (int k = 1; k <= 3; k++) {
298                 if (input[2].equals(examTypes[k])) {
299                     examTypeIndex = k;
300                     break;
301                 }
302             }
303             if (courseTypeIndex == -1 || examTypeIndex == -1) {
304                 // 未知的课程类型或考试类型,抛出异常或者默认值
305                 print.wrongFormat();
306             }
307             if (!((courseTypeIndex == 1 && examTypeIndex == 1)  // 必修+考试
308                     || (courseTypeIndex == 2 && examTypeIndex == 2)  // 选修+考察
309                     || (courseTypeIndex == 3 && examTypeIndex == 3))) {  // 实验+实验
310                 print.course_not_Match(input[0]);
311                 return;
312             }
313             if(courses.containsKey(input[0])) {
314                 return;
315             }
316             Course course = new Course(input[0], courseTypeIndex, examTypeIndex);
317             courses.put(input[0], course);
318             return;
319         }
320 
321         if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$")) {
322             if (courseSelections.stream().anyMatch(cs -> cs.student.getStudentNum().equals(input[0])
323                     && cs.student.getName().equals(input[1])
324                     && cs.course.getClassName().equals(input[2])))
325                 return;
326 
327             Student student = new Student(input[1], input[0]);
328             students.put(input[0], student);
329 
330             String classNum = input[0].substring(0, 6);
331             classes.computeIfAbsent(classNum, key -> {
332                 Class aClass = new Class(key);
333                 aClass.students = new HashMap<>();
334                 return aClass;
335             }).students.put(input[0], student);
336 
337             if (!courses.containsKey(input[2])) {
338                 print.course_not_Exist(input[2]);
339                 return;
340             }
341 
342             if (courses.get(input[2]).getAssessmentMethodology() != 1) {
343                 print.course_not_Match(input[0], input[1]);
344                 return;
345             }
346 
347             Course course = courses.get(input[2]);
348             CourseSelection courseSelection = new CourseSelection();
349             courseSelection.student = student;
350             courseSelection.course = course;
351             courseSelection.grade = new GradeA(Integer.parseInt(input[4]), Integer.parseInt(input[3]));
352             courseSelections.add(courseSelection);
353             return;
354         }
355 
356         if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|10{2})$")) {
357             if (courseSelections.stream().anyMatch(cs ->
358                     cs.student.getStudentNum().equals(input[0]) &&
359                             cs.student.getName().equals(input[1]) &&
360                             cs.course.getClassName().equals(input[2])))
361                 return;
362 
363             Student student = new Student(input[1], input[0]);
364             students.put(input[0], student);
365 
366             String classNum = input[0].substring(0, 6);
367             classes.computeIfAbsent(classNum, key -> {
368                 Class aClass = new Class(key);
369                 aClass.students = new HashMap<>();
370                 return aClass;
371             }).addStudent(student);
372 
373             if (!courses.containsKey(input[2])) {
374                 print.course_not_Exist(input[2]);
375                 return;
376             }
377 
378             if (courses.get(input[2]).getAssessmentMethodology() != 2) {
379                 print.course_not_Match(input[0], input[1]);
380                 return;
381             }
382 
383             Course course = courses.get(input[2]);
384             CourseSelection courseSelection = new CourseSelection();
385             courseSelection.student = student;
386             courseSelection.course = course;
387             int finalGrade = Integer.parseInt(input[3]);
388             courseSelection.grade = new GradeB(finalGrade);
389             courseSelections.add(courseSelection);
390             return;
391         }
392         if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((([0-9]|[1-9][0-9]|100)( ))+)([0-9]|[1-9][0-9]|100)$")) {
393             boolean selectionExists = courseSelections.stream().anyMatch(courseSelection ->
394                     courseSelection.student.getStudentNum().equals(input[0]) &&
395                             courseSelection.student.getName().equals(input[1]) &&
396                             courseSelection.course.getClassName().equals(input[2])
397             );
398             if (selectionExists) {
399                 return;
400             }
401 
402             Student student = students.computeIfAbsent(input[0], num -> new Student(input[1], num));
403             String classNum = input[0].substring(0, 6);
404             Class aClass = classes.computeIfAbsent(classNum, num -> {
405                 Class newClass = new Class(num);
406                 newClass.students = new HashMap<>();
407                 return newClass;
408             });
409             aClass.addStudent(student);
410 
411             Course course = courses.get(input[2]);
412             if (course == null) {
413                 print.course_not_Exist(input[2]);
414                 return;
415             }
416 
417             if (course.getAssessmentMethodology() != 3) {
418                 print.course_not_Match(input[0], input[1]);
419                 return;
420             }
421 
422             int usualNum = Integer.parseInt(input[3]);
423             if (input.length - 4 != usualNum) {
424                 print.course_not_Match(input[0], input[1]);
425                 return;
426             }
427             CourseSelection courseSelection = new CourseSelection();
428             courseSelection.student = student;
429             courseSelection.course = courses.get(input[2]);
430 
431             ArrayList<Integer> usualGrades = IntStream.rangeClosed(1, usualNum)
432                     .mapToObj(t -> Integer.parseInt(input[3 + t]))
433                     .collect(Collectors.toCollection(ArrayList::new));
434 
435             courseSelection.grade = new GradeC(usualGrades);
436             courseSelections.add(courseSelection);
437             return;
438         }
439         print.wrongFormat();
440     }
441 }
View Code

类图如下:

 

 设计思路:

  1. 创建必要的类(Course、Grade、Student、Class)来表示课程和成绩相关的信息,定义合适的属性和方法。

  2. 解析输入的课程信息和成绩信息:

    • 通过字符串分割和正则表达式等方式,将输入的信息解析为课程名称、课程性质、考核方式等课程信息。
    • 根据课程性质和考核方式,判断成绩信息应该属于哪种类型(考试、考察、实验)的成绩。
    • 将成绩信息解析为学号、姓名、课程名称、平时成绩、期末成绩等成绩信息。
  3. 根据课程信息和成绩信息的约束,进行合法性检查:

    • 检查课程信息中的课程性质和考核方式是否匹配。
    • 检查成绩是否超出范围,例如平时成绩和期末成绩的取值范围是[0,100]。
    • 检查学号、姓名等信息的合法性。
  4. 根据解析的数据构建对象并进行数据处理:

    • 创建Course对象,将课程信息存储到HashMap或ArrayList中,用于后续处理和输出。
    • 创建Grade对象,将成绩信息存储到HashMap或ArrayList中,用于后续处理和输出。
    • 创建Student对象,根据成绩信息计算总成绩平均分并存储到学生对象中。
    • 创建Class对象,根据学生信息计算班级总成绩平均分并存储到班级对象中。
  5. 处理数据并输出结果:

    • 遍历学生列表,按学号排序,并输出每个学生的学号、姓名、总成绩平均分。
    • 遍历课程列表,按课程名称排序,并输出每门课程的平时成绩平均分、期末考试平均分、总成绩平均分。
    • 遍历班级列表,按班级号排序,并输出每个班级的班级号、总成绩平均分。
  6. 处理异常情况:

    • 如果遇到格式错误、数据不合法或者其他异常情况,输出相应的错误提示信息。

第八次大作业:

课程成绩3:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.concurrent.atomic.AtomicReference;


public class Main {
    public static void main(String[] args) throws IOException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint();
    messageGetAndPrint.print = new Print();
    
    while (true) {
        String message = in.readLine();
        if ("end".equals(message)) {
            messageGetAndPrint.print.personPrint(messageGetAndPrint.students, messageGetAndPrint.courseSelections);
            messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses, messageGetAndPrint.courseSelections);
            messageGetAndPrint.print.classPrint(messageGetAndPrint.classes, messageGetAndPrint.courseSelections);
            break;
        }
        messageGetAndPrint.getMessage(message);
    }
}
}
class Class {
    private String classNum;
    HashMap<String , Student> students;
    Class(String classNum) {
        setClassNum(classNum);
    }
    public void setClassNum(String classNum) {
        this.classNum = classNum;
    }
    public String getClassNum() {
        return classNum;
    }
    public void addStudent(Student student) {
        students.put(student.getStudentNum() , student);
    }
}
class Student {
    private String name;
    private String studentNum;
    Student(String name , String studentNum) {
        setName(name);
        setStudentNum(studentNum);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getStudentNum() {
        return studentNum;
    }
    public void setStudentNum(String studentNum) {
        this.studentNum = studentNum;
    }
}
class Course {
    private String className;
    private int classQuality;
    private int assessmentMethodology;
    ArrayList<Float> weightFunction = new ArrayList<>();
    Course(String className , int classQuality , int assessmentMethodology) {
        setClassName(className);
        setClassQuality(classQuality);
        setAssessmentMethodology(assessmentMethodology);
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public int getClassQuality() {
        return classQuality;
    }
    public void setClassQuality(int classQuality) {
        this.classQuality = classQuality;
    }
    public int getAssessmentMethodology() {
        return assessmentMethodology;
    }
    public void setAssessmentMethodology(int assessmentMethodology) {
        this.assessmentMethodology = assessmentMethodology;
    }
}
class CourseSelection {
    Student student;
    Course course;
    Grade grade;
}

class Grade {
    SubItemGrades subItemGrades = new SubItemGrades();
    public int getGrade() {
        AtomicReference<Float> allGrades = new AtomicReference<>(0.0f);
        IntStream.range(0, subItemGrades.subItem.size()).forEach(i -> allGrades.updateAndGet(v -> v + subItemGrades.subItem.get(i) * subItemGrades.grades.get(i)));
        return allGrades.get().intValue();
    }
}
class SubItemGrades {
    ArrayList<Integer> grades = new ArrayList<>();
    ArrayList<Float> subItem = new ArrayList<>();
}
class Print {
    public void personPrint(HashMap<String, Student> students, ArrayList<CourseSelection> courseSelections) {
        Map<String, List<CourseSelection>> courseSelectionsByStudent = courseSelections.stream()
                .collect(Collectors.groupingBy(cs -> cs.student.getStudentNum()));

        List<String> sortedStudentKeys = new ArrayList<>(students.keySet());
        Collections.sort(sortedStudentKeys);

        sortedStudentKeys.forEach(key -> {
            StringBuilder output = new StringBuilder(students.get(key).getStudentNum() + " " + students.get(key).getName());
            List<CourseSelection> studentCourseSelections = courseSelectionsByStudent.get(key);

            if (studentCourseSelections == null || studentCourseSelections.isEmpty()) {
                output.append(" did not take any exams");
            } else {
                int averageGrade = studentCourseSelections.stream()
                        .mapToInt(cs -> cs.grade.getGrade())
                        .sum() / studentCourseSelections.size();
                output.append(" ").append(averageGrade);
            }

            System.out.println(output);
        });
    }
    public void coursePrint(HashMap<String, Course> courses, ArrayList<CourseSelection> courseSelections) {
        Map<String, List<CourseSelection>> courseGrades = courseSelections.stream()
                .collect(Collectors.groupingBy(cs -> cs.course.getClassName()));

        courses.values().stream()
                .sorted(Comparator.comparing(Course::getClassName))
                .map(Course::getClassName)
                .forEach(key -> {
                    List<CourseSelection> gradeList = courseGrades.computeIfAbsent(key, k -> new ArrayList<>());
                    int averageGrade;

                    if (!gradeList.isEmpty()) {
                        averageGrade = gradeList.stream()
                                .mapToInt(cs -> cs.grade.getGrade())
                                .sum() / gradeList.size();
                        System.out.printf("%s %d%n", key, averageGrade);
                    } else {
                        System.out.printf("%s has no grades yet%n", key);
                    }
                });
    }
    public void classPrint(HashMap<String, Class> classes, ArrayList<CourseSelection> courseSelections) {
        Map<String, List<CourseSelection>> classGrades = courseSelections.stream()
                .filter(cs -> classes.values().stream()
                        .anyMatch(c -> c.students.containsKey(cs.student.getStudentNum())))
                .collect(Collectors.groupingBy(cs -> classes.values().stream()
                        .filter(c -> c.students.containsKey(cs.student.getStudentNum()))
                        .findFirst().get().getClassNum()));

        classes.values().stream()
                .sorted(Comparator.comparing(Class::getClassNum))
                .map(Class::getClassNum)
                .forEach(key -> {
                    List<CourseSelection> gradeList = classGrades.computeIfAbsent(key, k -> new ArrayList<>());
                    int averageGrade;

                    if (!gradeList.isEmpty()) {
                        averageGrade = gradeList.stream()
                                .mapToInt(cs -> cs.grade.getGrade())
                                .sum() / gradeList.size();
                        System.out.printf("%s %d%n", key, averageGrade);
                    } else {
                        System.out.printf("%s has no grades yet%n", key);
                    }
                });
    }
    public void wrongFormat() {
        System.out.println("wrong format");
    }
    public void courseExist(String name) {
        System.out.println(name+" does not exist");
    }
    public void courseMatch(String studentNum , String studentName) {
        System.out.println(studentNum+" "+studentName+" : access mode mismatch");
    }
    public void courseMatch(String name) {
        System.out.println(name+" : course type & access mode mismatch");
    }
    public void numMatch(String name) {
        System.out.println(name+" : number of scores does not match");
    }
    public void weightValue(String name) {
        System.out.println(name+" : weight value error");
    }
}
class MessageGetAndPrint {
    Print print;
    HashMap<String , Class> classes = new HashMap<>();
    HashMap<String , Student> students = new HashMap<>();
    HashMap<String , Course> courses = new HashMap<>();
    ArrayList<CourseSelection> courseSelections = new ArrayList<>();
    public void getMessage(String getInput) {
        String[] message = getInput.split(" ");
        if(getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$") ||
                getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )((0.(0)+[1-9]|0.[1-9][0-9]*)( )(0.(0)+[1-9]|0.[1-9][0-9]*)$)") ||
                getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )([4-9])((( )(0.(0)+[1-9]|0.[1-9][0-9]*|1))*)(( )(0.(0)+[1-9]|0.[1-9][0-9]*))$")
        ) {
            int i=0,j=0;
            if (!courses.containsKey(message[0])) {
                switch (message[1]) {
                    case "必修" : i = 1;
                    case "选修" : i = 2;
                    case "实验" : i = 3;
                }
                switch (message[2]) {
                    case "考试":   j = 1;  break;
                    case "考察":   j = 2;  break;
                    case "实验":   j = 3;  break;
                }

                boolean mismatch = (i == 1 && j != 1) || (i == 3 && j != 3) || (i != 3 && j == 3);
                boolean invalidLength = (j == 1 && message.length != 5) ||
                        (j == 2 && message.length != 3) ||
                        (j == 3 && message.length - 4 != Integer.parseInt(message[3]));

                if (mismatch) {
                    print.courseMatch(message[0]);
                } else if (invalidLength) {
                    print.numMatch(message[0]);
                } else {
                    Course course = new Course(message[0], i, j);
                    float sumWeight = 0;

                    if (j == 1 || j == 3) {
                        for (int k = 0; k < (j == 1 ? 2 : Integer.parseInt(message[3])); k++) {
                            float weight = Float.parseFloat(message[4 + k]);
                            sumWeight += weight;
                            course.weightFunction.add(weight);
                        }
                    } else {
                        course.weightFunction.add(1F);
                        sumWeight = 1;
                    }

                    if (Math.abs(sumWeight - 1) > 0.001) {
                        print.weightValue(message[0]);
                    } else {
                        courses.put(message[0], course);
                    }
                }
            }
        }
        else if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)$") ||
                getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$") ||
                getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )((([0-9]|[1-9][0-9]|100)( ))*)([0-9]|[1-9][0-9]|100)$")
        ) {
            boolean courseSelectionExists = courseSelections.stream()
                    .anyMatch(courseSelection -> courseSelection.student.getStudentNum().equals(message[0])
                            && courseSelection.student.getName().equals(message[1])
                            && courseSelection.course.getClassName().equals(message[2]));

            if (courseSelectionExists) {
                return;
            }

            Student student = new Student(message[1], message[0]);
            students.put(message[0] , student);

            String classNum = message[0].substring(0 , 6);

            if (!classes.containsKey(classNum)) {
                Class aClass = new Class(classNum);
                aClass.students = new HashMap<>();
                classes.put(classNum , aClass);
            }

            classes.get(classNum).addStudent(student);

            if (!(courses.containsKey(message[2]))) {
                print.courseExist(message[2]);
            } else {
                if (message.length - 3 != courses.get(message[2]).weightFunction.size()) {
                    print.courseMatch(message[0], message[1]);
                    return;
                }

                CourseSelection courseSelection = new CourseSelection();
                courseSelection.student = student;
                courseSelection.course = courses.get(message[2]);

                Grade grade = new Grade();
                IntStream.range(0, message.length - 3)
                        .forEach(i -> grade.subItemGrades.grades.add(Integer.parseInt(message[3 + i])));

                grade.subItemGrades.subItem = courses.get(message[2]).weightFunction;
                courseSelection.grade = grade;

                courseSelections.add(courseSelection);
            }
        }
        else
            print.wrongFormat();
    }
}
View Code

类图如下:

 我并没有通过所有的测试点,以下测试点并没有通过:

题目的分析如下:

这道题目要求修改成绩类的继承关系为组合关系,使用组合关系将课程成绩类和分项成绩类组合起来。还新增了分项成绩的权重属性,并根据权重计算每个分项成绩的总成绩。

首先,需修改类结构如下:

  1. 定义一个"Course"类,包含课程名称、课程性质、考核方式和分项成绩数量等属性,并提供相应的构造方法和访问方法。

  2. 定义一个"GradeComponent"类,包含分项成绩的分值和权重属性,并提供相应的构造方法和访问方法。

  3. 定义一个"CourseGrade"类,包含该门课程的所有分项成绩和所属的课程对象,通过组合关系与"Course"和"GradeComponent"类建立关联。

  4. 定义一个"Grade"类,包含学号、姓名、成绩列表(包含"CourseGrade"对象)等属性,并提供相应的构造方法和访问方法。

  5. 定义一个"Student"类,包含学号、姓名、成绩列表(包含"CourseGrade"对象)等属性,并提供添加成绩、计算总成绩平均分等方法。

  6. 定义一个"Class"类,包含班级号、学生列表等属性,并提供按学号排序、计算班级总成绩平均分等方法。

其次,修改计算总成绩的方式:

  1. 考试课总成绩的计算方法不变,仍然为将平时成绩乘以平时成绩的权重再加上期末成绩乘以期末成绩的权重。

  2. 实验课总成绩的计算方法变为将每个实验成绩乘以实验成绩的权重,并累加所有分项成绩的总和。

期末考试:

 7-3 魔方排序问题

  1 import java.util.Scanner;
  2 import java.util.ArrayList;
  3 import java.util.Comparator;
  4 import java.math.BigDecimal;
  5 import java.math.RoundingMode;
  6 
  7 abstract class RubikCube implements Comparable<RubikCube>{
  8     protected String Color;
  9     protected int layer;
 10     Solid solid;
 11     @Override
 12     public int compareTo(RubikCube other) {
 13         return this.getVolume().compareTo(other.getVolume());
 14     }
 15     public RubikCube() {
 16     }
 17     public RubikCube(String Color,int layer,Solid solid){
 18         this.Color = Color;
 19         this.layer = layer;
 20         this.solid = solid;
 21     }
 22 
 23     public void setColor(String color) {
 24         Color = color;
 25     }
 26 
 27     public String getColor() {
 28         return Color;
 29     }
 30 
 31     public void setLayer(int layer) {
 32         this.layer = layer;
 33     }
 34 
 35     public int getLayer() {
 36         return layer;
 37     }
 38 
 39     public void setSolid(Solid solid) {
 40         this.solid = solid;
 41     }
 42 
 43     public Solid getSolid() {
 44         return solid;
 45     }
 46     public abstract double getArea();
 47     public abstract BigDecimal getVolume();
 48 
 49 }
 50 
 51 class SquareCube extends RubikCube {
 52 
 53     public SquareCube(String color, int layer, Solid solid) {
 54         super(color, layer, solid);
 55     }
 56 
 57     @Override
 58     public double getArea() {
 59         double unitArea = solid.getArea();
 60         return unitArea *  Math.pow(getLayer(), 2);  // Total surface area
 61     }
 62 
 63     @Override
 64     public BigDecimal getVolume() {
 65         double unitVolume = solid.getVolume();
 66         BigDecimal value = new BigDecimal(unitVolume * Math.pow(getLayer(), 3));
 67         BigDecimal rounded = value.setScale(2, RoundingMode.HALF_UP);
 68         return rounded;  // Total volume
 69     }
 70 }
 71 
 72 class RegularPyramidCube extends RubikCube {
 73 
 74     public RegularPyramidCube(String color, int layer, Solid solid) {
 75         super(color, layer, solid);
 76     }
 77 
 78     @Override
 79     public double getArea() {
 80         double unitArea = solid.getArea();
 81         return unitArea *  getLayer() * getLayer();
 82     }
 83 
 84     @Override
 85     public BigDecimal getVolume() {
 86         double unitVolume = solid.getVolume();
 87         return BigDecimal.valueOf(unitVolume * getLayer() * getLayer()*getLayer());
 88     }
 89 }
 90 abstract class Solid {
 91     protected double side;
 92     public Solid(){
 93     }
 94 
 95     public void setSide(double side) {
 96         this.side = side;
 97     }
 98 
 99     public double getSide() {
100         return side;
101     }
102     public Solid(double side) {
103         this.side = side;
104     }
105 
106     public abstract double getArea();
107 
108     public abstract double getVolume();
109 }
110 
111 class Cube extends Solid {
112     public Cube(){
113     }
114     public Cube(double side) {
115         super(side);
116     }
117 
118     @Override
119     public double getArea() {
120         return 6 * side * side;
121     }
122 
123     @Override
124     public double getVolume() {
125         return side * side * side;
126     }
127 }
128 
129 class RegularPyramid extends Solid {
130     public RegularPyramid(double side) {
131         super(side);
132     }
133 
134     public RegularPyramid(){
135     }
136     private double getHeight() {
137         return Math.sqrt(side * side - (side / 2) * (side / 2));
138     }
139     @Override
140     public double getArea() {
141         return (0.5 * side * side * Math.sin(Math.PI / 3) + (3 * side * getHeight() / 2));
142     }
143 
144     @Override
145     public double getVolume() {
146         return (Math.pow(side, 3) * Math.sqrt(2)) / 12;
147     }
148 }
149 
150 public class Main {
151     public static void main(String[] args) {
152         // TODO Auto-generated method stub
153         Scanner input = new Scanner(System.in);
154 
155         String color;
156         int layer;
157         double side;
158         RubikCube cube;
159 
160         ArrayList<RubikCube> list = new ArrayList<>();
161 
162         int choice = input.nextInt();
163 
164         while(choice != 0) {
165             switch(choice) {
166                 case 1://SquareCube
167                     color = input.next();
168                     layer = input.nextInt();
169                     side = input.nextDouble();
170                     cube = new SquareCube(color, layer,new Cube(side));
171                     list.add(cube);
172                     break;
173                 case 2://RegularPyramidCube
174                     color = input.next();
175                     layer = input.nextInt();
176                     side = input.nextDouble();
177                     cube = new RegularPyramidCube(color, layer,new RegularPyramid(side));
178                     list.add(cube);
179                     break;
180             }
181             choice = input.nextInt();
182         }
183 
184         list.sort(Comparator.naturalOrder());//正向排序
185 
186         for(int i = 0; i < list.size(); i++) {
187             System.out.print(list.get(i).getColor() + " " +
188                     String.format("%.2f", list.get(i).getArea()) + " " +
189                     String.format("%.2f", list.get(i).getVolume()) );
190             System.out.println("");
191         }
192     }
193 }
View Code

这题我并没有拿到满分,后来与同学交流发现可能是因为数据用的double类型,如果将所有的数据类型改变为BigDecimal,就能过了测试点。

​ Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

​ BigDecimal所创建的是对象,故我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

7-4 销售步枪问题(附加题)

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4     public static void main(String[] args) {
  5         Scanner in = new Scanner(System.in);
  6         int lockQuantity = in.nextInt();
  7         int stockQuantity = in.nextInt();
  8         int barrelQuantity = in.nextInt();
  9 
 10         try {
 11             SalesOrder order = new SalesOrder(lockQuantity, stockQuantity, barrelQuantity);
 12             System.out.printf("%.2f %.2f\n", order.calculateTotalSales(), order.calculateCommission());
 13         } catch (IllegalArgumentException e) {
 14             System.out.println(e.getMessage());
 15         }
 16     }
 17 }
 18 class Barrel {
 19     static  double UNIT_PRICE = 25;
 20     public Barrel(){
 21     }
 22     public Barrel(double UNIT_PRICE){
 23         this.UNIT_PRICE = UNIT_PRICE;
 24     }
 25 
 26     public static double getUnitPrice() {
 27         return UNIT_PRICE;
 28     }
 29 
 30     public static void setUnitPrice(double unitPrice) {
 31         UNIT_PRICE = unitPrice;
 32     }
 33 
 34     static boolean checkOrder(int quantity) {
 35         return quantity >= 0 && quantity <= 90;
 36     }
 37 
 38     static double calculatePrice(int quantity) {
 39         return quantity * UNIT_PRICE;
 40     }
 41 }
 42 
 43 class Stock {
 44     static  double UNIT_PRICE = 30;
 45     public static double getUnitPrice() {
 46         return UNIT_PRICE;
 47     }
 48 
 49     public Stock(){
 50     }
 51     public Stock(double UNIT_PRICE){
 52         this.UNIT_PRICE = UNIT_PRICE;
 53     }
 54     public static void setUnitPrice(double unitPrice) {
 55         UNIT_PRICE = unitPrice;
 56     }
 57 
 58     static boolean checkOrder(int quantity) {
 59         return quantity >= 0 && quantity <= 80;
 60     }
 61 
 62     static double calculatePrice(int quantity) {
 63         return quantity * UNIT_PRICE;
 64     }
 65 }
 66 
 67 
 68 class Lock {
 69     static  double UNIT_PRICE = 45;
 70 
 71     public static double getUnitPrice() {
 72         return UNIT_PRICE;
 73     }
 74 
 75     public Lock(){
 76     }
 77     public Lock(double UNIT_PRICE){
 78         this.UNIT_PRICE = UNIT_PRICE;
 79     }
 80     public static void setUnitPrice(double unitPrice) {
 81         UNIT_PRICE = unitPrice;
 82     }
 83     static boolean checkOrder(int quantity) {
 84         return quantity >= 0 && quantity <= 70;
 85     }
 86 
 87     static double calculatePrice(int quantity) {
 88         return quantity * UNIT_PRICE;
 89     }
 90 }
 91 
 92 
 93 class SalesOrder {
 94 
 95     int lockQuantity, stockQuantity, barrelQuantity;
 96 
 97     SalesOrder(int lockQuantity, int stockQuantity, int barrelQuantity) {
 98         if (!Lock.checkOrder(lockQuantity) || !Stock.checkOrder(stockQuantity) || !Barrel.checkOrder(barrelQuantity)) {
 99             throw new IllegalArgumentException("Wrong Format");
100         }
101         this.lockQuantity = lockQuantity;
102         this.stockQuantity = stockQuantity;
103         this.barrelQuantity = barrelQuantity;
104     }
105 
106     double calculateTotalSales() {
107         return Lock.calculatePrice(lockQuantity) + Stock.calculatePrice(stockQuantity) + Barrel.calculatePrice(barrelQuantity);
108     }
109 
110     double calculateCommission() {
111         double totalSales = calculateTotalSales();
112         if (totalSales <= 1000) {
113             return totalSales * 0.1;
114         } else if (totalSales <= 1800) {
115             return 1000 * 0.1 + (totalSales - 1000) * 0.15;
116         } else {
117             return 1000 * 0.1 + 800 * 0.15 + (totalSales - 1800) * 0.2;
118         }
119     }
120 }
View Code

这题我也没拿得到满分差了1分,后来结束之后多看了下,发现是枪机的数量范围不应该是0-70而应该是1-70。

 这题的结构照着给出的类图写就好了。

总结

Java大作业终于结束了啊啊啊!不用每个星期都受折磨了TAT。虽然学习Java的过程非常痛苦,但是也学到了很多。其实关于Java还有很多内容没有学习,越学越发现Java真的是一个很好的开发工具,有很多库函数和各种辅助的类。但是我本身感觉只学习到了一点面向对象设计程序的思想,还需要继续努力理解掌握学到的知识和探索学习新的知识。

 
 
 
posted @ 2023-12-05 21:05  sev2  阅读(35)  评论(0编辑  收藏  举报