BLOG-3

发布时间 2023-12-09 20:34:57作者: thefloweryou

一.前言

  本次博客主要对之前发布的7-8次PTA题目集(成绩计算系列)以及期末考试进行分析总结。此次博客是第三次也是本学期最后一次,通过这个学期的学习,我对Java的基础结构有了一定的了解,经历了多次PTA可以想象到java 行业卷的程度。课程成绩统计程序考察的知识点有使用String类提供的方法进行字符串的分割、替换和格式化;int、double等基本数据类型来存储和处理数值,使用数组来存储和操作一组数据,还有使用类和对象来组织和处理数据,使用类的属性和方法来进行数据的存储和处理;使用try-catch语句来捕获和处理可能发生的异常情况;使用Collections类提供的方法进行排序和遍历集合。

  这次题目主要为课程成绩统计程序2和3,以及部分Java进阶知识的应用,难度中等偏上,题量适中,涵盖了多个细节和要求,包括异常处理和特殊情况的处理。涉及到的知识点都是类、接口等。

二.设计与分析

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

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

 代码如下:

import java.util.Scanner;
import java.text.Collator;
import java.util.Locale;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        ArrayList<String> inputs = new ArrayList<>();

        String info = input.nextLine();
        while(!info.equals("end")){
            inputs.add(info);
            info = input.nextLine();
        }
        inputs.add(info);
        ArrayList<Course> courses = new ArrayList<>();
        ArrayList<Class1> classes = new ArrayList<>();
        ArrayList<Student> stu = new ArrayList<>();
        ArrayList<Selection> selections = new ArrayList<>();

        int i,j,k,n,m,q;
        for(i = 0;!inputs.get(i).equals("end");i++) {
            String[] Info = inputs.get(i).split(" ");
            if (inputs.get(i).matches(".{1,10}\\s(((必修|选修|实验)\\s(考试|考察|实验))|(必修))")) {
                if (inputs.get(i).contains("必修")) {

                    if (inputs.get(i).contains("考察")||inputs.get(i).contains("实验")) {
                        System.out.println(Info[0] + " : course type & access mode mismatch");
                    } else {
                        if (courses.size() == 0) {
                            Course course = new Course(Info[0], Info[1], "考试");
                            courses.add(course);
                        } else {
                            for (j = 0; j < courses.size(); j++) {
                                if (courses.get(j).getLessonName().equals(Info[0])) {
                                    break;
                                }
                            }
                            if (j == courses.size()) {
                                Course course = new Course(Info[0], Info[1], "考试");
                                courses.add(course);
                            }
                        }
                    }
                } else if (inputs.get(i).contains("选修")) {
                    if (inputs.get(i).contains("实验")) {
                        System.out.println(Info[0] + " : course type & access mode mismatch");
                    }else{
                        if (courses.size() == 0) {
                            Course course = new Course(Info[0], Info[1], Info[2]);
                            courses.add(course);
                        } else {
                            for (j = 0; j < courses.size(); j++) {
                                if (courses.get(j).getLessonName().equals(Info[0])) {
                                    break;
                                }
                            }
                            if (j == courses.size()) {
                                Course course = new Course(Info[0], Info[1], Info[2]);
                                courses.add(course);
                            }
                        }
                    }
                }
                else if(inputs.get(i).contains("实验")){
                    if(inputs.get(i).contains("考试")||inputs.get(i).contains("考察")){
                        System.out.println(Info[0] + " : course type & access mode mismatch");
                    }
                    else {
                        if (courses.size() == 0) {
                            Course course = new Course(Info[0], Info[1], Info[2]);
                            courses.add(course);
                        } else {
                            for (j = 0; j < courses.size(); j++) {
                                if (courses.get(j).getLessonName().equals(Info[0])) {
                                    break;
                                }
                            }
                            if (j == courses.size()) {
                                Course course = new Course(Info[0], Info[1], Info[2]);
                                courses.add(course);
                            }
                        }
                    }
                }
            }
            else if(inputs.get(i).matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}(\\s([\\d]{1,2}|100)){1,2}")) {
                for (j = 0; j < classes.size(); j++) {
                    if (classes.get(j).getNum().equals(Info[0].substring(0, 6))) {
                        break;//找到了
                    }
                }
                if (j == classes.size()) {//班级不存在
                    Class1 class1 = new Class1(Info[0].substring(0, 6));
                    classes.add(class1);
                }
                for (k = 0; k < classes.get(j).students.size(); k++) {
                    if (classes.get(j).students.get(k).getId().equals(Info[0])) {
                        break;//学生存在
                    }
                }
                if (k == classes.get(j).students.size()) {//学生不存在
                    Student student = new Student(Info[0], Info[1]);
                    classes.get(j).students.add(student);
                    stu.add(student);
                }
                if (Info.length == 4) {//选修考察

                    int flag = 0;
                    for (n = 0; n < courses.size(); n++) {
                        if (courses.get(n).getLessonName().equals(Info[2])) {
                            break;
                        }
                    }
                    if (n == courses.size()) {
                        System.out.println(Info[2] + " does not exist");
                        flag = 1;
                    }
                    if (courses.size() > 0) {
                        if (flag == 0) {
                            if (courses.get(n).getTestWay().equals("考察")) {
                                for (m = 0; m < selections.size(); m++) {
                                    if (selections.get(m).getStudent().getId().equals(classes.get(j).students.get(k).getId())
                                            && selections.get(m).getCourse().getLessonName().equals(courses.get(n).getLessonName())) {
                                        break;
                                    }
                                }
                                if (m == selections.size()) {
                                    int fGrade = Integer.parseInt(Info[3]);
                                    Score examine = new Examine(fGrade);
                                    Selection selection = new Selection(courses.get(n), classes.get(j).students.get(k), examine);
                                    selections.add(selection);
                                }
                            }
                            else if(courses.get(n).getTestWay().equals("实验")&&(Integer.parseInt(Info[3])<4||Integer.parseInt(Info[3])>9)){
                                classes.remove(classes.size()-1);
                                stu.remove(stu.size()-1);
                                System.out.println("wrong format");
                            }
                            else{
                                System.out.println(classes.get(j).students.get(k).getId() + " " +
                                        classes.get(j).students.get(k).getName() + " : " + "access mode mismatch");
                            }
                        }
                    }
                } else if (Info.length == 5) {//考试

                    int flag = 0;
                    for (n = 0; n < courses.size(); n++) {
                        if (courses.get(n).getLessonName().equals(Info[2])) {
                            break;
                        }
                    }
                   
                    if (courses.size() > 0) {
                        if(flag == 0) {
                            if (courses.get(n).getTestWay().equals("考试")) {
                                for (m = 0; m < selections.size(); m++) {
                                    if (selections.get(m).getStudent().getId().equals(classes.get(j).students.get(k).getId())
                                            && selections.get(m).getCourse().getLessonName().equals(courses.get(n).getLessonName())) {
                                        break;
                                    }
                                }
                                if (m == selections.size()) {
                                    int uGrade = Integer.parseInt(Info[3]);
                                    int fGrade = Integer.parseInt(Info[4]);
                                    Score examScore = new ExamScore(uGrade, fGrade);
                                    Selection selection = new Selection(courses.get(n), classes.get(j).students.get(k), examScore);
                                    selections.add(selection);
                                }
                            } else if(courses.get(n).getTestWay().equals("实验")&&(Integer.parseInt(Info[3])<4||Integer.parseInt(Info[3])>9)){
                                classes.remove(classes.size()-1);
                                stu.remove(stu.size()-1);
                                System.out.println("wrong format");
                            }
                            else  {
                                System.out.println(classes.get(j).students.get(k).getId() + " " +
                                        classes.get(j).students.get(k).getName() + " : " + "access mode mismatch");
                            }
                        }
                    }
                }
            }
            else if (inputs.get(i).matches
                    ("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}\\s[4-9](\\s([\\d]{1,2}|100))+")){
                for (j = 0; j < classes.size(); j++) {
                    if (classes.get(j).getNum().equals(Info[0].substring(0, 6))) {
                        break;//找到了
                    }
                }
                if (j == classes.size()) {//班级不存在
                    Class1 class1 = new Class1(Info[0].substring(0, 6));
                    classes.add(class1);
                }
                for (k = 0; k < classes.get(j).students.size(); k++) {
                    if (classes.get(j).students.get(k).getId().equals(Info[0])) {
                        break;//学生存在
                    }
                }
                if (k == classes.get(j).students.size()) {//学生不存在
                    Student student = new Student(Info[0], Info[1]);
                    classes.get(j).students.add(student);
                    stu.add(student);
                }
                    int flag = 0;
                    int testScores = 0;
                    for (n = 0; n < courses.size(); n++) {
                        if (courses.get(n).getLessonName().equals(Info[2])) {
                            break;
                        }
                    }
                    if (n == courses.size()) {
                        System.out.println(Info[2] + " does not exist");
                        flag = 1;
                    }
                    if (courses.size() > 0) {
                        if(flag == 0) {
                            if(!courses.get(n).getTestWay().equals("实验")){
                                classes.remove(classes.size()-1);
                                stu.remove(stu.size()-1);
                                System.out.println("wrong format");
                            }
                            else{
                                if (courses.get(n).getTestWay().equals("实验")&&Info.length - 4== Integer.parseInt(Info[3])) {
                                    for (m = 0; m < selections.size(); m++) {
                                        if (selections.get(m).getStudent().getId().equals(classes.get(j).students.get(k).getId())
                                                && selections.get(m).getCourse().getLessonName().equals(courses.get(n).getLessonName())) {
                                            break;
                                        }
                                    }
                                    if (m == selections.size()) {
                                        for(q = 4;q < Info.length;q++)
                                            testScores = testScores + Integer.parseInt(Info[q]);
                                        Score testScore = new TestScore(testScores,Integer.parseInt(Info[3]));
                                        Selection selection = new Selection(courses.get(n), classes.get(j).students.get(k), testScore);
                                        selections.add(selection);
                                    }
                                } else  {
                                    System.out.println(classes.get(j).students.get(k).getId() + " " +
                                            classes.get(j).students.get(k).getName() + " : " + "access mode mismatch");
                                }
                            }
                        }
                    }
            }
            else System.out.println("wrong format");
        }
//排序
        ArrayList<Integer> averScore = new ArrayList<>();
        ArrayList<Integer> gradeSize = new ArrayList<>();
        for(i = 0;i < stu.size();i++){
            averScore.add(stu.get(i).getAverageScore());

            gradeSize.add(stu.get(i).grades.size());
        }

        for(i = 0;i < stu.size()-1;i++){
            String temp;
            int tp;
            for(j = 0;j < stu.size()-1-i;j++) {
                if(stu.get(j + 1).getIntId() < stu.get(j).getIntId()){
                    temp = stu.get(j+1).getId();
                    stu.get(j+1).setId(stu.get(j).getId());
                    stu.get(j).setId(temp);
                    temp = stu.get(j+1).getName();
                    stu.get(j+1).setName(stu.get(j).getName());
                    stu.get(j).setName(temp);
                    tp = averScore.get(j+1);
                    averScore.set(j+1,averScore.get(j));
                    averScore.set(j,tp);
                    tp = gradeSize.get(j+1);
                    gradeSize.set(j+1,gradeSize.get(j));
                    gradeSize.set(j,tp);
                }
            }
        }
        ArrayList<Integer> averUgrade = new ArrayList<>();
        ArrayList<Integer> averFgrade = new ArrayList<>();
        ArrayList<Integer> averGrade = new ArrayList<>();
        Collections.sort(courses);
        for(i = 0;i < courses.size();i++){
            averUgrade.add(courses.get(i).getAverageUrades());
            averFgrade.add(courses.get(i).getAverageFrades());
            averGrade.add(courses.get(i).getAverageScore());
        }
        for(i = 0;i < stu.size();i++){
            System.out.print(stu.get(i).getId()+" "+stu.get(i).getName()+" ");
            if(gradeSize.get(i)!= 0) {
                System.out.println(averScore.get(i));
            }
            else System.out.println("did not take any exams");
        }
        for(i = 0;i < courses.size();i++) {
            System.out.print(courses.get(i).getLessonName() + " ");
            if (courses.get(i).grades.size() != 0) {
                if (courses.get(i).getTestWay().equals("考试")) {
                    System.out.print(averUgrade.get(i) + " ");

                    System.out.print(averFgrade.get(i) + " ");
                } else if(courses.get(i).getTestWay().equals("考察"))
                    System.out.print(averFgrade.get(i) + " ");

                System.out.println(averGrade.get(i));
            }
            else System.out.println("has no grades yet");
        }
        ArrayList<Integer> classScore = new ArrayList<>();
        for(i = 0;i < classes.size();i++){
            classScore.add(classes.get(i).getClassScore());
        }
        for(i = 0;i < classes.size()-1;i++){
            String temp;
            int tp;
            for(j = 0;j < classes.size()-1-i;j++){
                if(classes.get(j+1).getIntNum() < classes.get(j).getIntNum()){
                    temp = classes.get(j+1).getNum();
                    classes.get(j+1).setNum( classes.get(j).getNum());
                    classes.get(j).setNum(temp);
                    tp = classScore.get(j+1);
                    classScore.set(j+1,classScore.get(j));
                    classScore.set(j,tp);
                }
            }
        }
        for(i = 0;i < classes.size();i++){
            System.out.print(classes.get(i).getNum()+" ");
            if(classScore.get(i) != 0)
                System.out.println(classScore.get(i));
            else System.out.println("has no grades yet");
        }
    }
}
abstract  class Score {
    private int Fgrade;
    private int Ugrade;
    
    public Score(int fgrade) {
        Fgrade = fgrade;
    }
    public Score(int ugrade, int fgrade) {
        super();
        Ugrade = ugrade;
        Fgrade = fgrade;
    }
    public abstract int getScore();
    public int getUgrade() {
        return Ugrade;
    }
    public int getFgrade() {
        return Fgrade;
    }
}


class Examine extends Score{
    public Examine(int fgrade){
        super(fgrade);
    }
    @Override
    public int getScore(){
        return (int)( this.getFgrade());
    }
}
class ExamScore extends Score{
    public ExamScore(int ugrade, int fgrade) {
        super(ugrade, fgrade);
    }
    @Override
    public int getScore(){
        return (int)(this.getUgrade()*0.3 + this.getFgrade()*0.7);
    }
}
class TestScore extends Score{
    public TestScore(int testScores,int num){
        super(testScores,num);
    }
    @Override
    public int getScore(){
        if(this.getFgrade() != 0)
            return this.getUgrade()/this.getFgrade();
        else 
            return 0;
    }
}
class Course implements Comparable<Course> {
    private String lessonName;
    private String lessonAttribute;
    private String testWay;

    ArrayList<Integer> grades = new ArrayList<>();
    ArrayList<Integer> Ugrades = new ArrayList<>();
    ArrayList<Integer> Fgrades = new ArrayList<>();
    public Course(String lessonName) {
        super();
        this.lessonName = lessonName;
    }
    public Course(String lessonName, String lessonAttribute, String testWay) {
        super();
        this.lessonName = lessonName;
        this.lessonAttribute = lessonAttribute;
        this.testWay = testWay;
    }
    public String getLessonName() {return lessonName;}
    public String getLessonAttribute() {
        return lessonAttribute;
    }
    public String getTestWay() {
        return testWay;
    }
    public int getAverageScore() {
        int total = 0;
        for(int i = 0;i < grades.size();i++){
            total = total + grades.get(i);
        }
        if(grades.size() != 0)
        return total/grades.size();
        else return 0;
    }
    public int getAverageUrades() {
        int total = 0;
        for(int i = 0;i < Ugrades.size();i++){
            total = total + Ugrades.get(i);
        }
        if(Ugrades.size() != 0)
            return total/Ugrades.size();
        else 
            return 0;
    }
    public int getAverageFrades() {
        int total = 0;
        for(int i = 0;i < Fgrades.size();i++){
            total = total + Fgrades.get(i);
        }
        if(Fgrades.size() != 0)
            return total/Fgrades.size();
        else 
            return 0;
    }
    @Override
    public int compareTo(Course cou) {
        Comparator<Object> com = Collator.getInstance(Locale.CHINA);
        return ((Collator) com).compare(this.lessonName,cou.getLessonName());
    }
}
class Class1 {
    private String num;
    ArrayList<Student> students = new ArrayList<>();
    public Class1(String num) {
        this.num = num;
    }
    public String getNum() {
        return num;
    }
    public void setNum(String num){
        this.num = num;
    }
    public int getIntNum(){
        return Integer.parseInt(num);
    }
    public int getClassScore(){
        int total = 0;
        for(int i = 0;i < this.students.size();i++){
            total = total +this.students.get(i).getAverageScore();
        }
        if(this.students.size() == 0){
            return 0;
      }
        else return total/this.students.size();
    }
}


 class Selection {
    private Course course;
    private Student student;
    private Score score;
    public Selection(Course course, Student student, Score score) {
        this.course = course;
        this.student = student;
        this.score = score;
        this.student.grades.add(score.getScore());
        this.course.grades.add(score.getScore());
        if(course.getTestWay().equals("考试")){
            this.course.Ugrades.add(score.getUgrade());
            this.course.Fgrades.add(score.getFgrade());
        }
        else if(course.getTestWay().equals("考察")){
            this.course.Fgrades.add(score.getFgrade());
        }
    }
    public Course getCourse() {
        return course;
    }
    public Student getStudent() {
        return student;
    }
    public Score getScore() {
        return score;
    }
}
class AssessmentScore extends Score{
    int finalScore;
    public AssessmentScore(int finalScore) {
        this.finalScore = finalScore;
    }
    public int getFinalScore() {
        return finalScore;
    }
    public int getScore(){
        return finalScore;
    }
}
class Student {
    private String id;
    private String name;
    ArrayList<Integer> grades = new ArrayList<>();
    private int averScore;
    public Student(String id,String name) {
        this.id = id;
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public int getIntId(){
        return Integer.parseInt(id);
    }
    public void setId(String id) {
        this.id = id;
    }
    public int getAverageScore() {
        int total = 0;
       for(int i = 0;i < grades.size();i++){
           total = total + grades.get(i);
       }
       if(grades.size() != 0) {
           this.averScore = total / grades.size();
           return averScore;
       }
       else return 0;
    }
}
课程成绩统计程序-2

类图如下:

 

分析:

本题需要注意以下几点:输入格式和信息的相关约束(如权重默认为0.3、0.7,成绩是整数,不包含小数部分,成绩的取值范围是【0,100】等)。

输出格式和信息的相关约束(如平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数,成绩平均分只取整数部分,小数部分丢弃等)。
异常情况的处理,如解析某个成绩信息时,课程名称不在已输入的课程列表中,输入的成绩数量和课程的考核方式不匹配,输入的课程性质和课程的考核方式不匹配等。
需要使用多个类来实现程序的功能,包括 Course、Grade、Student、Class 等,根据类图进行设计。

主要是在学生成绩二中有了实验课,实验课由于次数的不确定性,与必修与选修的判定有所不同:相对应的性质不是在固定的位置,所以需要用其他的变量来辅助表示,才能准确地表示出相应的数据。其次,每一门课程的分数计算方法都不同,需要分别来表示,这个写在了相应的类中。

 

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

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

 代码如下:

 import java.text.Collator;
 import java.util.*;
 
 public class Main {
       static ArrayList<Student> students = new ArrayList<>();
       static ArrayList<Class> classes = new ArrayList<>();
       static ArrayList<Course> courses = new ArrayList<>();
     public static void main(String[] args) {
         Scanner input = new Scanner(System.in);
         String string = input.nextLine();
         while (!string.equals("end")){
             analyse(string);
             string = input.nextLine();
         }
         showMessage();
     }
     public static void analyse(String string){
         Match match = new Match();
         int flag = match.match(string);
         switch (flag){
             case 0:
                 System.out.println("wrong format");
                 break;
             case 1:
                 courseMessage(string);
                 break;
             case 2:
                 scoreMessage(string);
                 break;
             default:
                 break;
         }
     }
    
     public static void courseMessage(String string){
         String[] str = string.split(" ");
         String name = str[0];
         String nature = str[1];
         String method = str[2];
         
         if(checkCourse(name,nature,method)){
             if (searchCourse(name) == null) {
                 switch (method) {
                     case "考察":
                         courses.add(new Course(name, nature, method));
                         break;
                     case "考试": {
                         double[] weights = {Double.parseDouble(str[3]), Double.parseDouble(str[4])};
                         Course course = new Course(name, nature, method);
                        course.setWeights(2, weights);
                        courses.add(course);
                         break;
                     }
                     case "实验": {
                         int n = Integer.parseInt(str[3]);
                         double[] weights = new double[n];
                         for (int i = 4, j = 0; i < str.length; i++, j++) {
                             weights[j] = Double.parseDouble(str[i]);
                         }
                         Course course = new Course(name, nature, method);
                         course.setWeights(n, weights);
                         courses.add(course);
                         break;
                     }
                 }
             }
         }
    }
      //检查课程
      public static boolean checkCourse(String name,String nature, String method){
         if(nature.equals("必修") && method.equals("考试")) {
             return true;
         }
          else if(nature.equals("选修")){
             return method.equals("考试") || method.equals("考察");
          }
          else if(nature.equals("实验") && method.equals("实验")){
              return true;
          }
          System.out.println(name+" : course type & access mode mismatch");
          return false;
     }
      //搜索课程
      public static Course searchCourse(String name){
          for (Course course:courses) {
              if(course.name.equals(name))
                  return course;
          }
          return null;
      }
      //添加成绩信息
      public static void scoreMessage(String string){
          String[] str = string.split(" ");
          String ID = str[0];
          String number = ID.substring(0,6);
       String name = str[1];
          String courseName = str[2];
  
         Class cla;
         //如果该班级第一次出现
         if(searchClass(number) == null){
             cla = new Class(number);
             classes.add(cla);
         }
         //如果该班级存在
        else {
             cla = searchClass(number);
         }
 
         Student student;
         if(searchStudent(ID)==null){
             student = new Student(ID,name);
             students.add(student);
             if (cla != null) {
                 cla.addStudent(student);
             }
         }
         //如果该学生存在
         student = searchStudent(ID);
 
         //如果课程不存在
        if(searchCourse(courseName)==null){
             System.out.println(courseName+" does not exist");
         }
         //如果课程存在
         else if(searchCourse(courseName)!=null){
             Course course = searchCourse(courseName);
             //考试
             if(Objects.requireNonNull(course).method.equals("考试") && str.length == 5){
                 int dailyScore = Integer.parseInt(str[3]);
                 int finalScore = Integer.parseInt(str[4]);
                ExamScore score = new ExamScore(dailyScore,finalScore);
                 Selection selection = new Selection(course,student,score);
                 if (student != null && searchSelection(student, course) == null) {
                     course.addSelection(selection);
                     student.addSelection(selection);
                 }
             }
            
              else if(course.method.equals("考察") && str.length == 4){
                 int finalScore = Integer.parseInt(str[3]);
                AssessmentScore score = new AssessmentScore(finalScore);
                 Selection selection = new Selection(course,student,score);
                 if (student != null && searchSelection(student, course) == null) {
                     course.addSelection(selection);
                     student.addSelection(selection);
                 }
             }
             //实验
              else if(course.method.equals("实验")){
                  int times = Integer.parseInt(str[3]);
                  if(str.length == 4 + times){
                      ExperimentScore score =new ExperimentScore();
                      Selection selection = new Selection(course,student,score);
                      for (int i=4; i<str.length; i++){
                          score.addGrade(str[i]);
                      }
                      if (student != null && searchSelection(student, course) == null) {
                          course.addSelection(selection);
                          student.addSelection(selection);
                      }
                  }
                  else{
                     System.out.println(ID + " " + name + " : access mode mismatch");
                 }
             }
             else {
                 System.out.println(ID + " " + name + " : access mode mismatch");
             }
         }
     }
     public static Selection searchSelection(Student student,Course course){
         for (Selection selection: student.selections){
             if(selection.course.equals(course)){
                 return selection;
             }
         }
         return null;
     }
     public static Class searchClass(String number){
         for (Class cla:classes) {
             if(cla.number.equals(number)){
                 return cla;
             }
         }
         return null;
     }
     //搜索学生
     public static Student searchStudent(String ID){
         for (Student student:students) {
             if(student.ID.equals(ID))
                 return student;
         }
         return null;
     }
     //输出学生,课程,班级信息
    public static void showMessage(){
         Collections.sort(students);
         for (Student stu:students) {
             stu.printStudent();
         }
         Collections.sort(courses);
         for (Course course:courses) {
             course.printCourse();
         }
         Collections.sort(classes);
         for (Class cla:classes) {
             cla.printClass();
         }
     }
     static class Match{
         String stuNumMatch = "[0-9]{8}";//8个0-9的数字
          String stuNameMatch = "\\S{1,10}";//1到10个非空格(TAB)字符
          String scoreMatch = "([1-9]?[0-9]|100)";
          String courseNameMatch = "\\S{1,10}";//1到10个非空格(TAB)字符
         String courseTypeMatch = "(选修|必修|实验)";
          String checkCourseTypeMatch = "(考试|考察|实验)";
         //courseInput用于定义课程信息模式(正则表达式)
          String courseInput = courseNameMatch + " " + courseTypeMatch + " " + checkCourseTypeMatch;
         //scoreInput用于定义成绩信息模式(正则表达式)
          String scoreInput1 = stuNumMatch + " " + stuNameMatch + " " + courseNameMatch + " " + scoreMatch;         //考察
          String scoreInput2 =  stuNumMatch + " " + stuNameMatch + " " + courseNameMatch + " " + scoreMatch + " " + scoreMatch;         //考试
          String scoreInput3 = stuNumMatch + " " + stuNameMatch + " " + courseNameMatch;         //考察
 
         public int match(String string){
 //            if (matchingScore(string))
 //                return 2;
             return matchingCourse(string);
         }
         //课程信息
         // 1即格式正确,0即格式错误,-1即数量或者比重错误
         private  int matchingCourse(String s) {
             String[] str = s.split(" ");
             int flag = 0;
             if(str[2].equals("考察")){
                 flag = assessmentCourseMatching(s);
            }
             if(str[2].equals("考试")){
                 flag = examCourseMatching(s);
             }
             if(str[2].equals("实验")){
                 flag = experimentCourseMatching(s);
             }
             return flag;
         }
         //考察
         public  int assessmentCourseMatching(String s){
             if(s.matches(courseInput))
                 return 1;
             return 0;
         }
         //考试
         public  int examCourseMatching(String s){
             String[] str = s.split(" ");
             String courseLine = str[0] +" "+ str[1] +" "+ str[2];
             if(courseLine.matches(courseInput)){
                 double weight = Double.parseDouble(str[3])+Integer.parseInt(str[4]);
                 if(weight==1){
                     return 1;
                 }
                 else{
                     System.out.println(str[0]+" : weight value error");
                     return -1;
                 }
             }
             return 0;
         }
         //实验
         public  int experimentCourseMatching(String s){
             String[] str = s.split(" ");
             String courseLine = str[0] +" "+ str[1] +" "+ str[2];
             if(courseLine.matches(courseInput)){
                 double weight = 0;
                 int n = Integer.parseInt(str[3]);
                 if(4+n != str.length){
                     System.out.println(str[0]+" : number of scores does not match");
                    return -1;
                }
                 for (int i=4; i<str.length; i++){
                     weight += Double.parseDouble(str[i]);
                }
                 if(weight==1){
                     return 1;
                 }
                 else{
                     System.out.println(str[0]+" : weight value error");
                     return -1;
                 }
             }
             return 0;
         }
         //成绩信息
         private  boolean matchingScore(String s) {
             int flag = matchingExperimentScore(s);
             switch (flag){
                 case 0:
                     return true;
                 case 1:
                     return false;
                 case 2:
             }
             return s.matches(scoreInput1) || s.matches(scoreInput2);
         }

         private  int matchingExperimentScore(String s) {
             String[] str = s.split(" ");
             String courseName = str[2];
             Course course = searchCourse(courseName);
            if(course.method.equals("实验")){
                 StringBuilder scoreInput = new StringBuilder(scoreInput3);
                 for (int i=0; i<course.n; i++){
                     scoreInput.append(" ").append(scoreMatch);
                 }
                 if(s.matches(scoreInput.toString())){
                     return 0;
                 }
                 else {
                    return 1;
                 }
             }
            return 2;
         }
     }
 }
class Life {
    private boolean crossRiver=false;
    private boolean isAlive=true;
    private boolean hasCross=false;
    boolean getcrossRiver()
    {
        return crossRiver;
    }
    boolean gethasCross()
    {
        return hasCross;
    }
    boolean getisAlive()
    {
        return isAlive;
    }
    
    void setcrossRiver()
    {
        crossRiver=!crossRiver;
    }
    void sethasCross()
    {
        hasCross=!hasCross;
    }
    void setisAlive()
    {
        isAlive=!isAlive;
    }
  
}
class Dog extends Animal {
    public String getAnimalClass(){
        return "狗";
    }
    public String Shout(){
        return "汪汪";
    }
}
 class Class implements Comparable<Class>{
     String number;
     ArrayList<Student> students = new ArrayList<>();
     public Class(String number) {
        this.number = number;
     }
     public void addStudent(Student student){
         this.students.add(student);
     }
     public int getAverageScore(){
         int sum = 0;
         int n = students.size();
         for (Student stu:students){
             if(stu.selections.size() != 0){
                 sum += stu.getAverageScore();
             }
             else {
                 n--;
             }
         }
         return sum /n;
     }
     public boolean scoreIsNull(){
         for (Student stu:students) {
             if(stu.selections.size()!=0){
                 return false;
             }
         }
         return true;
     }
     //输出班级信息
     public void printClass(){
         if(scoreIsNull()){
             System.out.println(number+" has no grades yet");
         }
         else {
             System.out.println(number+" "+getAverageScore());
         }
     }
     //排列
     @Override
     public int compareTo(Class o) {
         return number.compareTo(o.number);
     }
 }
class Cat extends Animal{
    public String getAnimalClass(){
        return "猫";
    }
    public String Shout(){
        return "喵喵";
    }
}


 class Student implements Comparable<Student>{
    String ID;
     String name;
     ArrayList<Selection> selections = new ArrayList<>();
     public Student(String ID, String name) {
         this.ID = ID;
         this.name = name;
     }
     public void addSelection(Selection selection){
         this.selections.add(selection);
     }
     //输出学生信息
     public void printStudent(){
         if(selections.size() == 0){
             System.out.println(ID+" "+name+" did not take any exams");
         }
         else {
             System.out.println(ID+" "+name+" "+getAverageScore());
         }
     }
     //个人平均成绩
     public int getAverageScore(){
         int sum = 0;
         for (Selection s : selections) {
             sum += s.score.getScore();
        }
         return sum / selections.size();
     }
     
     @Override
     public int compareTo(Student o) {
         return this.ID.compareTo(o.ID);
     }
 }
class Goat extends Animal{
    public String getAnimalClass(){
        return "山羊";
    }
    public String Shout(){
        return "咩咩";
    }
}

 class Selection{
     Course course;
     Student student;
     Score score;
     public Selection(Course course, Student student, Score score) {
         this.course = course;
         this.student = student;
         this.score = score;
     }
 }
class Animal{
    private String type;
    private String shout;
    
    public String getAnimalClass(){
        return type;
    }
    public String Shout(){
        return shout;
    }
}

 class Course implements Comparable<Course>{
     String name;
     String nature;
     String method;
     int n = 0;
     double[] weights;
     ArrayList<Selection> selections = new ArrayList<>();
     public Course(String name, String nature, String method) {
         this.name = name;
         this.nature = nature;
         this.method = method;
     }
     public void setWeights(int n,double[] weights){
         this.n = n;
         this.weights = weights;
     }
     public void addSelection(Selection selection){
        this.selections.add(selection);
     }
     public int getAverageDailyScore(){
         int sum = 0;
         for (Selection s:selections) {
             sum += s.score.getDailyScore();
         }
         return sum /selections.size();
     }
     public int getAverageFinalScore(){
        int sum = 0;
         for (Selection s:selections) {
             sum += s.score.getFinalScore();
         }
         return sum /selections.size();
     }
     public int getAverageScore(){
         int sum = 0;
         for (Selection s:selections){
             sum += s.score.getScore();
        }
         return sum/selections.size();
     }
     public void printCourse(){
         if(selections.size() == 0){
             System.out.println(name+" has no grades yet");
         }
         else if(method.equals("考察")){
             System.out.println(name+" "+getAverageFinalScore()+" "+getAverageScore());
         }
         else if(method.equals("考试")){
             System.out.println(name+" "+getAverageDailyScore()+" "+getAverageFinalScore()+" "+getAverageScore());
         }
         else if(method.equals("实验")){
             System.out.println(name+" "+getAverageScore());
         }
     }
     public int compareTo(Course o) {
         Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
         return compare.compare(name,o.name);
     }
 }

 class Score{
     public int getScore(){
         return 0;
     }
     public int getDailyScore() {
         return 0;
     }
     public int getFinalScore() {
         return 0;
     }
 
 }

 class AssessmentScore extends Score{
     int finalScore;
     public AssessmentScore(int finalScore) {
         this.finalScore = finalScore;
     }
     public int getFinalScore() {
         return finalScore;
     }
     public int getScore(){
         return finalScore;
     }
 }
class Circle{
    private double radius;
    
    public Circle(double radius){
        this.radius=radius;
    }
    
    public void getArea(){
        double area=0;
        if(radius<=0)
            System.out.println("Wrong Format");
        else{
            area=Math.PI*radius*radius;
            System.out.println(String.format("%.2f",area) );
        }
    }
}
 class ExamScore extends Score{
     int dailyScore;
     int finalScore;
     public ExamScore(int dailyScore, int finalScore) {
         this.dailyScore = dailyScore;
       this.finalScore = finalScore;
     }
     public int getDailyScore() {
         return dailyScore;
     }
     public int getFinalScore() {
         return finalScore;
     }
  public int getScore(){
         return (int) (0.3*dailyScore+0.7*finalScore);
     }
 }

 class ExperimentScore extends Score{
     ArrayList<Integer> grades = new ArrayList<>();
     public ExperimentScore() {
     }
    public void addGrade(String grade){
         this.grades.add(Integer.parseInt(grade));
     }
     public int getScore() {
         int sum = 0;
         for (int grade:grades) {
             sum += grade;
         }
         return sum /grades.size();
    }
 }
课程成绩统计程序-3

类图如下:

 

 分析:

在设计程序时,要注意处理一些异常情况,如输入格式错误、课程名称不存在、成绩数量和考核方式不匹配等。通过将成绩类的继承关系改为组合关系,可以更灵活地适应变更。组合关系可以实现更多种类的关联,而不仅仅局限于继承关系。当需求发生变化时,只需要修改组合关系中的对象即可,而不需要修改整个类结构。这样可以更好地满足程序的可扩展性和可维护性要求。

 这个题目花的时间不多,所以得分较低,比较惭愧。这个题目在第二次的基础上修改了计算总成绩的方式,通过权重值来计算总成绩,如果使用之前的代码没有那么好修改,所以进行了一下重构。首先没有再次使用正则表达式,换成了用数组对应位置的检测来判断输入的成绩类型;同时增加了权重的相应计算;还有Map以及List的运用,使得代码更加简洁便于修改;Map可以很方便的进行学号班级成绩的排序,很好的简化了代码。

期末考试

7-1 立体图形问题

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

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

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

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;
public class Main {
    public static void display(Solid solid) {
        System.out.println(String.format("%.2f", solid.getSurfaceArea()));
        System.out.println(String.format("%.2f", solid.getVolume()));
    }

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

        Solid cube = new Cube(side);
        Solid pyramid = new RegularPyramid(side, side);

        display(cube);
        display(pyramid);
    }
}
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;
    private double height;

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

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

    @Override
    public double getVolume() {
        return Math.sqrt(2) * side * side * side / 12;
    }
}
立体图形问题

分析:这个题目比较简单,一开始输出正三棱锥的体积数据不对,但是将公式改一下,即答案正确了。

在main方法中,首先创建一个Scanner对象input,用于读取用户输入。然后读取用户输入的边长,并根据该边长创建一个立方体对象和一个正三棱锥对象。最后,调用display方法分别显示它们的表面积和体积。总之,这段代码通过抽象类和多态的方式实现了计算不同几何形状的表面积和体积的功能,并通过用户输入来使用这些功能。每个几何形状都有自己特定的计算方法,通过重写抽象类中的方法来实现。

 7-2 魔方问题

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

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

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

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

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;
public class Main {
    public static void display(RubikCube cube) {
        System.out.println(cube.getColor());
        System.out.println(String.format("%.2f", cube.getSurfaceArea()));
        System.out.println(String.format("%.2f", cube.getVolume()));
    }

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

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;
    private double height;

    public RegularPyramid(double side) {
        this.side = side;
        this.height = side * Math.sqrt(2.0 / 3.0);
    }

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

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

abstract class RubikCube extends Solid {
    private String color;
    private int layer;

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

    public String getColor() {
        return color;
    }

    public int getLayer() {
        return layer;
    }
}

class SquareCube extends RubikCube {
    private Solid unitCube;

    public SquareCube(String color, int layer, Solid unitCube) {
        super(color, layer);
        this.unitCube = unitCube;
    }

    @Override
    public double getSurfaceArea() {
        return unitCube.getSurfaceArea() * Math.pow(getLayer(), 2);
    }

    @Override
    public double getVolume() {
        return unitCube.getVolume() * Math.pow(getLayer(), 3);
    }
}

class RegularPyramidCube extends RubikCube {
    private Solid unitPyramid;

    public RegularPyramidCube(String color, int layer, Solid unitPyramid) {
        super(color, layer);
        this.unitPyramid = unitPyramid;
    }

    @Override
    public double getSurfaceArea() {
        return unitPyramid.getSurfaceArea() * Math.pow(getLayer(), 2);
    }

    @Override
    public double getVolume() {
        return unitPyramid.getVolume() * Math.pow(getLayer(), 3);
    }
}
魔方问题

分析:代码扩展了之前的立体类和子类,引入了魔方(RubikCube)以及魔方的特殊形式:正方形魔方(SquareCube)和正三棱锥魔方(RegularPyramidCube)。同时,在Main类中实现了对这些新类的使用。这段代码通过继承和多态的方式,实现了对魔方及其特殊形式的建模,并通过用户输入来创建和展示不同类型的魔方对象的特征。最后输出时,要注意公式,与第一题是一样的细节问题。

7-3 魔方排序问题

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

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

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

..循环..

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

 分析:这个题目很可惜,没有得分,加上代码改的比较乱就不贴过来了,也是在前两个题目的基础上增加一些细节。通过继承、多态和排序等概念,实现了对魔方立方体及其特殊形式的建模,并能够根据用户输入创建和展示不同类型的魔方立方体对象的特征。

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

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

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

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

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

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

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

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

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

 

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

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

 代码如下:

import java.util.Scanner;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int lock;
        int gunMachine = input.nextInt();
        int gunStock = input.nextInt();
        int gunBarrel = input.nextInt();

        if (gunMachine > 70 || gunStock > 80 || gunBarrel > 90) {
            System.out.println("Wrong Format");
            return;
        }

        SalesOrder order = new SalesOrder(gunMachine, gunStock, gunBarrel);
        System.out.printf("%.2f %.2f", order.getSalesAmount(), order.getCommission());
    }
}
class SalesOrder {
    private int gunMachine;
    private int gunStock;
    private int gunBarrel;
    private double salesAmount;
    private double commission;

    public SalesOrder(int gunMachine, int gunStock, int gunBarrel) {
        this.gunMachine = gunMachine;
        this.gunStock = gunStock;
        this.gunBarrel = gunBarrel;
        this.salesAmount = gunMachine * 45 + gunStock * 30 + gunBarrel * 25;
        this.commission = calculateCommission(salesAmount);
    }

    public double getSalesAmount() {
        return salesAmount;
    }

    public double getCommission() {
        return commission;
    }
    
    private double calculateCommission(double amount) {
        if (amount <= 1000) {
            return amount * 0.1;
        } 
        else if (amount <= 1800) {
            return 1000 * 0.1 + (amount - 1000) * 0.15;
        } 
        else {
            return 1000 * 0.1 + 800 * 0.15 + (amount - 1800) * 0.2;
        }
    }
}
abstract class BARREL {
    public abstract double getPrice();
    public abstract double getSumprice();
}
销售步枪问题(附加题)

分析:Main类的main方法是程序的入口。首先使用Scanner对象读取用户输入的销售数据。然后通过条件判断检查销售数据格式是否正确,如果超过生产限额或格式错误,输出"Wrong Format"并结束程序。接着创建SalesOrder对象,并检查订单数据是否有效。最后计算总销售额和佣金,并将结果格式化输出。代码实现了一个销售订单系统,用户可以输入销售数据(gunMechanisms、gunStocks和gunBarrels),然后根据输入的销售数量计算总销售额和佣金。

三.踩坑心得

1.在第二次题目中计算学生平均成绩的逻辑问题,使用Math.round方法可能导致精度误差。建议使用BigDecimal类进行精确计算,并在最后取整作为最终成绩。这是一个非常好的解决方案,BigDecimal类可以确保计算结果的精确性,避免了四舍五入带来的误差。在计算平均成绩时,可以使用BigDecimal类进行累加和除法运算,然后使用setScale方法设置精度和取整方式,以获得准确的平均成绩。

2.在两次成绩题目中获得了许多关于代码码提交过程中的经验教训。提交代码时,我们要注意输入的数据范围和格式,并进行实际的测试验证。同时,我们还要关注代码的可读性和可维护性,使用合适的数据结构和算法,并避免不必要的错误。此外,注重输入验证和异常处理对于确保代码的正确性和稳定性至关重要。通过应用这些心得,可以提高代码的质量和可靠性,并更好地满足题目要求。

3.数组越界问题:在处理输入时,需要注意数组越界的问题。例如,当解析学生信息时,需要确保课程索引在合法范围内,否则可能导致数组越界异常。
算法的设计和实现:在计算平均成绩时,需要设计合适的算法来处理课程成绩和权重。例如,我使用两个循环来遍历课程成绩和分项成绩,并计算总成绩。

4.编写代码时,要注意可读性和可维护性,使用合适的命名、注释和代码结构。可以考虑封装一些功能成函数,提高代码的可维护性。

5.Java编译器和运行时环境会给出非常详细的错误信息。当你遇到错误时,要认真阅读错误信息,并且知道如何正确解决问题。有时候错误信息可能会有些晦涩难懂,这时候可以尝试搜索相关问题并查看社区的解答。

四.改进建议

1. 使用面向对象的设计:考虑将学生、课程和成绩等信息封装成对象,以提高代码的可读性和可维护性。可以创建Student、Course、Grade等类来表示相关的实体,并在类中定义适当的方法和属性来处理相关操作。

2.错误处理和异常处理:在处理输入时,需要考虑错误处理和异常处理。例如,当解析学生信息时,可以使用try-catch块来捕获可能的异常,如数组越界异常等,并进行相应的处理。

3.我觉得代码应该多一些注释行,以便于下次再看和修改,代码最好多用方法和类,以免代码过于繁杂而看不懂。

4.希望老师能在每次作业截止之后及时把答案发出来给同学们参考并及时公布每次作业各个测试点的详细信息,让学生能更好的查缺补漏提升自己。我觉得代码应该多一些注释行,以便于下次再看和修改,代码最好多用方法和类,以免代码过于繁杂而看不懂。

5.减少内存使用:Java程序在内存管理方面拥有一定的优势,但仍然需要注意内存使用情况。确保及时释放不再使用的对象,避免内存泄漏问题。可以使用一些内存分析工具来监测和解决内存问题。

6.掌握调试技巧:在开发过程中,经常会遇到错误和异常。学会使用调试工具和技巧,能够更快地定位和解决问题。同时,养成良好的代码习惯,编写可读性强、易于调试的代码。

五.总结

经过这些题目集,我对输入验证、精确计算、数据结构优化等方面有了更深的理解。我将课本上Java的基本语法都过了一遍,包括变量、数据类型、运算符、控制流等。这些基础知识是编写Java程序的基石,掌握了这些知识之后才能进一步深入学习。我还学到了错误处理和异常处理的重要性,以及如何编写适当的单元测试来验证代码的正确性。我也意识到自己还有很多需要进一步学习和研究的地方。首先,我需要进一步学习和掌握更多的面向对象的设计原则和模式,以便更好地设计和实现代码。其次,我需要深入了解不同的数据结构和算法,并了解它们的优缺点,以便在实际的编程中能够选择合适的数据结构和算法。此外,我还需要进一步学习和研究关于异常处理和错误处理的最佳实践,以及如何编写更全面和有效的单元测试。在学习java的过程中感觉很痛苦,但是当真正掌握到知识点后是非常有成就感的,也告诫自己,学习就是要静下心来,并且花时间去消化所学知识,去沉淀,否则依然是迷糊不清楚的。在以后的学习过程中,要不骄不躁,每一次的学习都会有不同的收获。