一、前言
第三次作业主要针对课程成绩统计程序的迭代以及期末考试的总结
课程程序2是在第一次的基础上增加了实验课的情况,由于我程序1的框架打的不好,时间过了很久之后记忆不深,加之程序2开始的比较晚,又重新打了一个框架,但仍然很乱很碎,最后匆忙赶了两天也只拿了80分
课程程序3在第二次的基础上修改了计算总成绩的方式,并修改了成绩类的组成关系。由于课程程序2的框架也很混乱,于是我索性又重新建立了框架(以后写东西,一定要第一次就把框架搭好),并优化了很多信息判断类的代码。这次开始时间较早,于是类之间关系建立的比较清晰,后期修改匹配功能要求也更为完善便捷。同时,我发现相对于继承,我更喜欢成绩类使用组合的方式完成。但也侧面显示我对继承使用的不熟练,还需多花时间额外练习。
期末考试主要问题在于时间没有分配好,一开始三道程序题花的时间太久,有一些计算公式不太清楚,导致结果出现偏差。而后最后一道题也没时间去写了。除此之外,选择题一些题干阅读的不太仔细,有粗心失分的情况。
二、设计与分析
题目:
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.*; public class Main { public static void main(String[] args) { InputClass inputClass = new InputClass(); inputClass.input(); Output output = new Output(inputClass.getCourseSelections(),inputClass.getClassrooms()); output.studentSumAverage(); output.courseSumAverage(inputClass); output.classroomSumAverage(inputClass); } } //***输入类****// class InputClass { //输入类包含选课和班级的动态数组 ArrayList<CourseSelection> courseSelections; ArrayList<Classroom> classrooms; public InputClass() { this.courseSelections = new ArrayList<>(); // 初始化courseSelections this.classrooms = new ArrayList<>(); } public void input() { int sum = 0; Scanner scanner = new Scanner(System.in); Course t1 = new Course("null","null","null"); O: while (true) { String inputLine = scanner.nextLine(); String[] inputs = inputLine.split(" "); if (inputLine.equals("end")){ break O; } else if (inputLine.matches("^\\p{L}+\\s{1}\\p{L}+\\s{1}\\p{L}+$")) { //如果输入符合课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式 if(inputs[1].equals("必修")&&inputs[2].equals("考察")){ //如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配 System.out.println(inputs[0]+" : course type & access mode mismatch"); } else if (inputs[1].equals("实验")&&!inputs[2].equals("实验")) { System.out.println(inputs[0]+" : course type & access mode mismatch"); } else if (!inputs[1].equals("实验")&&inputs[2].equals("实验")) { System.out.println(inputs[0]+" : course type & access mode mismatch"); } else{ Course newcourse = new Course(inputs[0], inputs[1], inputs[2]); Score newscore = new ExperientScore(0,0); CourseSelection courseSelection = new CourseSelection(); //输入的课程名称、课程性质和考核方式赋给courseSelection对象的course属性 courseSelection.setCourse(newcourse); courseSelection.setScore(newscore); this.courseSelections.add(courseSelection);//将该courseSelection对象添加进动态数组courseSelections中 } } else if (inputLine.matches("^\\d+\\s{1}\\p{L}+\\s{1}\\p{L}+\\s{1}\\d+\\s{1}\\d+$")) { //如果输入符合课程信息格式:学号0+英文空格+姓名1+英文空格+课程名称2+英文空格+平时成绩3+英文空格+期末成绩4 if(findcourseByCourseName(inputs[2]).equals("null")){ System.out.println(inputs[0]+" "+inputs[1]+" "+" :"+inputs[2]+" does not exist"); }else{ Student newstudent = new Student(inputs[0],inputs[1]); Course newcourse = new Course(inputs[2],findpropertyByCourseName(inputs[2]),findevaluationMethodByCourseName(inputs[2])); String classNumber = newstudent.getStudentId().substring(0, 6); Classroom classroom = findClassroom(classNumber);CourseSelection courseSelection = new CourseSelection(); courseSelection.setStudent(newstudent); //先默认为考察方式 Score newscore = new AssessmentScore(Double.parseDouble(inputs[3]),Double.parseDouble(inputs[4])); //如果为考试方式,更改 if(findevaluationMethodByCourseName(inputs[2]).equals("考试")){ Score newscore0 = new ExamScore(Double.parseDouble(inputs[3]),Double.parseDouble(inputs[4])); newscore = newscore0; } courseSelection.setCourse(newcourse); courseSelection.setScore(newscore); this.courseSelections.add(courseSelection); if (classroom != null) { classroom.addStudent(newstudent); } else { Classroom newClassroom = new Classroom(classNumber); classrooms.add(newClassroom); newClassroom.addStudent(newstudent); } } } else if (inputLine.matches("^\\d+\\s{1}\\p{L}+\\s{1}\\p{L}+\\s{1}\\d+$")) { //如果输入符合课程信息格式:学号0+英文空格+姓名1+英文空格+课程名称2+英文空格+期末成绩3 if(findcourseByCourseName(inputs[2]).equals("null")){ System.out.println(inputs[0]+" "+inputs[1]+" "+" :"+inputs[2]+" does not exist"); }else{ Student newstudent = new Student(inputs[0],inputs[1]); Course newcourse = new Course(inputs[2],findpropertyByCourseName(inputs[2]),findevaluationMethodByCourseName(inputs[2])); String classNumber = newstudent.getStudentId().substring(0, 6); Classroom classroom = findClassroom(classNumber);CourseSelection courseSelection = new CourseSelection(); courseSelection.setStudent(newstudent); //先默认为考察方式 Score newscore = new AssessmentScore(0.0,Double.parseDouble(inputs[3])); //如果为考试方式,更改 if(findevaluationMethodByCourseName(inputs[2]).equals("考试")){ Score newscore0 = new ExamScore(0.0,Double.parseDouble(inputs[3])); newscore = newscore0; } courseSelection.setCourse(newcourse); courseSelection.setScore(newscore); this.courseSelections.add(courseSelection); if (classroom != null) { classroom.addStudent(newstudent); } else { Classroom newClassroom = new Classroom(classNumber); classrooms.add(newClassroom); newClassroom.addStudent(newstudent); } } }else if (findpropertyByCourseName(inputs[2]).equals("实验") && Integer.parseInt(inputs[3])>=4 && Integer.parseInt(inputs[3])<= 9) { if(findcourseByCourseName(inputs[2]).equals("null")){ System.out.println(inputs[0]+" "+inputs[1]+" "+" :"+inputs[2]+" does not exist"); }else{ Student newstudent = new Student(inputs[0], inputs[1]); Course newcourse = new Course(inputs[2], findpropertyByCourseName(inputs[2]), findevaluationMethodByCourseName(inputs[2])); String classNumber = newstudent.getStudentId().substring(0, 6); Classroom classroom = findClassroom(classNumber); CourseSelection courseSelection = new CourseSelection(); courseSelection.setStudent(newstudent); Score newscore = new ExperientScore(0, 0); if( inputs.length == 4+Integer.parseInt(inputs[3])) { //实验课程成绩信息包括:学号0、姓名1、课程名称2、实验次数3、每次成绩实验次数至少4次,不超过9次 //存储实验次数 int counttimes = Integer.parseInt(inputs[3]); double sum0 = 0; for (int i = 1; i <= counttimes; i++) { sum0 += Integer.parseInt(inputs[i + 3]); }//求实验总成绩 sum = (int) Math.floor(sum0 / counttimes); newscore = new ExperientScore(0, sum); courseSelection.setCourse(newcourse); courseSelection.setScore(newscore); this.courseSelections.add(courseSelection); if (classroom != null) { classroom.addStudent(newstudent); } else { Classroom newClassroom = new Classroom(classNumber); classrooms.add(newClassroom); newClassroom.addStudent(newstudent); } }else{ System.out.println(inputs[0]+" "+inputs[1]+" : access mode mismatch"); courseSelection.setCourse(newcourse); courseSelection.setScore(newscore); this.courseSelections.add(courseSelection); if (classroom != null) { classroom.addStudent(newstudent); } else { Classroom newClassroom = new Classroom(classNumber); classrooms.add(newClassroom); newClassroom.addStudent(newstudent); } } } } else{ System.out.println("wrong format"); } } } //以下可以根据遍历选课数组,找到指定课程所含的课程性质(选修/必修) public String findcourseByCourseName(String courseName) { for (CourseSelection courseSelection : courseSelections) { if (courseSelection.getCourse().getName().equals(courseName)) { return courseSelection.getCourse().getName(); } } return "null";//未找到该课程,返回空值 } public Course findcourseByCourseName0(String courseName) { for (CourseSelection courseSelection : courseSelections) { if (courseSelection.getCourse().getName().equals(courseName)) { return courseSelection.getCourse(); } } return null;//未找到该课程,返回空值 } //以下可以根据遍历选课数组,找到指定课程所含的课程性质(选修/必修) public String findpropertyByCourseName(String courseName) { for (CourseSelection courseSelection : courseSelections) { if (courseSelection.getCourse().getName().equals(courseName)) { return courseSelection.getCourse().getProperty(); } } return "null";//未找到该课程,返回空值 } //以下可以根据遍历选课数组,找到指定课程所含的考试方式(考试/考察) public String findevaluationMethodByCourseName(String courseName) { for (CourseSelection courseSelection : courseSelections) { if (courseSelection.getCourse().getName().equals(courseName)) { return courseSelection.getCourse().getEvaluationMethod(); } } return null;//未找到该课程,返回空值 } public Classroom findClassroom(String classNumber) { for (Classroom classroom : classrooms) { if (classroom.getClassNumber().equals(classNumber)) { return classroom; } } return null; } //以下可以根据遍历选课数组,找到指定id学生此时的总成绩 public Double findScoreByStudentName(String StudentId) { for (CourseSelection courseSelection : courseSelections) { if(courseSelection.getStudent()!=null) if (courseSelection.getStudent().getStudentId().equals(StudentId)) { return courseSelection.getScore().calculateTotalGrade(); } }return 0.0; } public ArrayList<CourseSelection> getCourseSelections() { return courseSelections; } public ArrayList<Classroom> getClassrooms() { return classrooms; } } class Output{ ArrayList<CourseSelection> courseSelections; ArrayList<Classroom> classrooms; public Output(ArrayList<CourseSelection> courseSelections,ArrayList<Classroom> classrooms){ this.courseSelections = courseSelections; this.classrooms = classrooms; } public void output(){ } InputClass t = new InputClass(); //****计算并输出每个学生所有课程总成绩的平均分****// public void studentSumAverage() { HashMap<String, Double> studentGrades = new HashMap<>(); HashMap<String, String> studentNames = new HashMap<>(); for (CourseSelection courseSelection : courseSelections) { Student student = courseSelection.getStudent(); if (student != null) { Score score = courseSelection.getScore(); if (score != null) { double totalGrade = score.calculateTotalGrade(); String studentId = student.getStudentId(); String name = student.getName(); if (studentGrades.containsKey(studentId)) { double sum = studentGrades.get(studentId) + totalGrade; studentGrades.put(studentId, sum); } else { studentGrades.put(studentId, totalGrade); studentNames.put(studentId, name); } } } } TreeMap<String, Double> sortedGrades = new TreeMap<>(studentGrades); for (String studentId : sortedGrades.keySet()) { double grade = sortedGrades.get(studentId); double average = grade / courseCountForStudent(studentId); // 计算平均成绩 String name = studentNames.get(studentId); if ((int) Math.floor(average) == 0) System.out.println(studentId + " " + name + " did not take any exams"); else System.out.println(studentId + " " + name + " " + (int) Math.floor(average)); } /*//System.out.println(studentGrades.get("20201103")); for (String studentId : studentGrades.keySet()) {// double grade = studentGrades.get(studentId); double average = grade / courseCountForStudent(studentId); // 计算平均成绩 String name = studentNames.get(studentId); if((int)Math.floor(average) == 0) System.out.println(studentId + " " + name + " did not take any exams"); else System.out.println(studentId + " " + name + " " + (int)Math.floor(average)); }*/ } // 辅助方法,用于计算学生选课数目 private int courseCountForStudent(String studentId) { int count = 0; for (CourseSelection courseSelection : courseSelections) { Student student = courseSelection.getStudent(); if (student != null && student.getStudentId().equals(studentId)) { count++; } } return count; } //****计算并输出每个课程总成绩的平均分****// public void courseSumAverage(InputClass t) { HashMap<String, List<Double>> courseScoresMap = new HashMap<>(); // 存放每门课程的成绩列表 // 遍历 courseSelections for (CourseSelection selection : courseSelections) { Course course = selection.getCourse(); if (selection.getCourse() != null) { String courseName = selection.getCourse().getName(); // 获取课程名 double regularScore = (int)Math.floor(selection.getScore().getRegularScore()); // 获取平时成绩 double finalScore = (int)Math.floor(selection.getScore().getFinalScore()); // 获取期末成绩 double totalGrade = (int)Math.floor(selection.getScore().calculateTotalGrade()); // 获取总成绩 //System.out.println(courseName+totalGrade); if(totalGrade == 0) continue; List<Double> scores = new ArrayList<>(); //System.out.println(courseName+":"+totalGrade); scores.add(regularScore); scores.add(finalScore); scores.add(totalGrade); if (selection.getStudent() == null && selection.getScore().calculateTotalGrade() == 0) { //courseScoresMap.put(courseName, scores); //System.out.println(courseName+"?"); } else { if (courseScoresMap.containsKey(courseName)) { List<Double> existingScores = courseScoresMap.get(courseName); // 累加新的平时成绩、期末成绩和总成绩 existingScores.set(0, existingScores.get(0) + regularScore); // 平时成绩 existingScores.set(1, existingScores.get(1) + finalScore); // 期末成绩 existingScores.set(2, existingScores.get(2) + totalGrade); // 总成绩 //System.out.println(courseName+":::"+existingScores.get(2)+":;"+totalGrade); t.findcourseByCourseName0(courseName).setCount(1); } else { courseScoresMap.put(courseName, scores); } } } } TreeMap<String, List<Double>> sortedCourseScoresMap = new TreeMap<>(new Comparator<String>() { @Override public int compare(String courseName1, String courseName2) { return courseName1.compareTo(courseName2); } }); sortedCourseScoresMap.putAll(courseScoresMap); for (Map.Entry<String, List<Double>> entry : sortedCourseScoresMap.entrySet()) { String courseName = entry.getKey(); List<Double> scores = entry.getValue(); int count = t.findcourseByCourseName0(courseName).getCount(); double regularScoreSum = scores.get(0); double finalScoreSum = scores.get(1); double totalGradeSum = scores.get(2); double regularScoreAvg = regularScoreSum / (count+1); double finalScoreAvg = finalScoreSum / (count+1); double totalGradeAvg = totalGradeSum / (count+1); //System.out.println(courseName+entry.getValue()+"!"); if (regularScoreSum > 0 || finalScoreSum > 0 || totalGradeSum > 0) { if (t.findevaluationMethodByCourseName(courseName).equals("考试")) System.out.println(courseName + " " + (int) Math.floor(regularScoreAvg) + " " + (int) Math.floor(finalScoreAvg) + " " + (int) Math.floor(totalGradeAvg)); else if ((t.findevaluationMethodByCourseName(courseName).equals("考察"))) System.out.println(courseName + " " + (int) Math.floor(finalScoreAvg) + " " + (int) Math.floor(totalGradeAvg)); else if ((t.findevaluationMethodByCourseName(courseName).equals("实验"))) System.out.println(courseName + " " + (int) Math.floor(totalGradeAvg)); } else { System.out.println(courseName + " has no grades yet"); } } } /*public void courseSumAverage(InputClass t) { HashMap<String, double[]> courseScoresMap = new HashMap<>(); // 遍历 courseSelections for (CourseSelection selection : courseSelections) { Course course = selection.getCourse(); if (selection.getCourse()!=null){ //System.out.println(selection.getCourse().getName()); //如果此时课程和学生都不为空 String courseName = selection.getCourse().getName();//获取课程名 double regularScore = selection.getScore().getRegularScore();//获取平时成绩 double finalScore = selection.getScore().getFinalScore();//获取期末成绩 double totalGrade = selection.getScore().calculateTotalGrade();//获取总成绩 double[] scores = {regularScore, finalScore, totalGrade}; //System.out.println(selection.getCourse().getName()+totalGrade); if(selection.getStudent()==null && selection.getScore().calculateTotalGrade()==0){ courseScoresMap.put(courseName, scores); }else{ if (courseScoresMap.containsKey(courseName)) { double[] existingScores = courseScoresMap.get(courseName); double[] count = courseScoresMap.get(courseName); // 累加新的平时成绩、期末成绩和总成绩 existingScores[0] += (int)Math.floor(scores[0]); // 平时成绩 existingScores[1] += (int)Math.floor(scores[1]); // 期末成绩 double s = 0; s = existingScores[2]; existingScores[2] += (int)Math.floor(scores[2]); // 总成绩 // 平均计算 //如果累加上不等于累加前的值,执行 if(s!=0) { existingScores[0] /= 2; // 平时成绩 existingScores[1] /= 2; // 期末成绩 existingScores[2] /= 2; // 总成绩 } //System.out.println(courseName+existingScores[2]); // 更新 HashMap courseScoresMap.put(courseName, existingScores); } else { courseScoresMap.put(courseName, scores); } }} } TreeMap<String, double[]> sortedCourseScoresMap = new TreeMap<>(new Comparator<String>() { @Override public int compare(String courseName1, String courseName2) { return courseName1.compareTo(courseName2); } }); sortedCourseScoresMap.putAll(courseScoresMap); sortedCourseScoresMap.putAll(courseScoresMap); HashMap<String, double[]> result = courseScoresMap; for (Map.Entry<String, double[]> entry : sortedCourseScoresMap.entrySet()) { boolean hasGrades = false; double[] scores = entry.getValue(); for (double score : scores) { if (score > 0) { hasGrades = true; break; } } String courseName = entry.getKey(); //System.out.println(courseName+" "+scores[0]+" "+scores[1]+" "+scores[2]); if (hasGrades) { hasGrades = false; if (t.findevaluationMethodByCourseName(courseName).equals("考试")) System.out.println(courseName + " " + (int) Math.floor(scores[0]) + " " + (int) Math.floor(scores[1]) + " " + (int) Math.floor(scores[2])); else if ((t.findevaluationMethodByCourseName(courseName).equals("考察"))) System.out.println(courseName + " " + (int) Math.floor(scores[1]) + " " + (int) Math.floor(scores[2])); else if ((t.findevaluationMethodByCourseName(courseName).equals("实验"))) System.out.println(courseName + " " + (int) Math.floor(scores[2])); }else { System.out.println(courseName +" has no grades yet"); } } // 输出结果 }*/ public class ClassroomComparator implements Comparator<Classroom> { @Override public int compare(Classroom c1, Classroom c2) { return Integer.parseInt(c1.getClassNumber()) - Integer.parseInt(c2.getClassNumber()); } } public void classroomSumAverage(InputClass t) { // 对classrooms列表按班级编号排序 Collections.sort(classrooms, new ClassroomComparator()); for (Classroom classroom : classrooms) { double averageScore = classroom.getAverageScore(t); if ((int) Math.floor(averageScore) == 0) { System.out.println(classroom.getClassNumber() + " has no grades yet"); } else { System.out.println(classroom.getClassNumber() + " " + (int) Math.floor(averageScore)); } } } /*public void classroomSumAverage(InputClass t) { for (Classroom classroom : classrooms) { double averageScore = classroom.getAverageScore(t); if((int)Math.floor(averageScore) == 0) System.out.println(classroom.getClassNumber()+" has no grades yet"); else{ System.out.println(classroom.getClassNumber()+" "+(int)Math.floor(averageScore)); } } }*/ } class CourseSelection { private Course course; // 课程 private Student student; // 学生 private Score score; // 成绩 public CourseSelection() { } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Score getScore() { return score; } public void setScore(Score score) { this.score = score; } } class Student { private String studentId; private String name; // 构造方法 public Student(String studentId, String name) { this.studentId = studentId; this.name = name; } // 学号属性的 getter 和 setter 方法 public String getStudentId() { return studentId; } public void setStudentId(String studentId) { this.studentId = studentId; } // 姓名属性的 getter 和 setter 方法 public String getName() { return name; } public void setName(String name) { this.name = name; } } class Course { private String name; private String property; private String evaluationMethod; private int count; // 构造方法 public Course(String name, String property, String evaluationMethod) { this.name = name; this.property = property; this.evaluationMethod = evaluationMethod; } // 课程名称属性的 getter 和 setter 方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCount() { return count; } public void setCount(int count) { this.count += count; } // 课程性质属性的 getter 和 setter 方法 public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } // 考核方式属性的 getter 和 setter 方法 public String getEvaluationMethod() { return evaluationMethod; } public void setEvaluationMethod(String evaluationMethod) { this.evaluationMethod = evaluationMethod; } } //****成绩的抽象类和抽象方法****/// abstract class Score { protected double regularScore; protected double finalScore; public Score(double regularScore,double finalScore) { this.regularScore = regularScore; this.finalScore = finalScore; } public abstract double getRegularScore(); public abstract double getFinalScore(); public abstract double calculateTotalGrade(); } class ExperientScore extends Score{ public ExperientScore(double regularScore, double finalScore) { super(regularScore,finalScore);//将传入的finalScore值传递给父类,以便在父类中进行适当的初始化。 } @Override public double getRegularScore() { return regularScore; } @Override public double getFinalScore() { return finalScore; } @Override public double calculateTotalGrade() { return finalScore; } } //*****考试成绩,由平时成绩和期末成绩加权计算******// class ExamScore extends Score { public ExamScore(double regularScore, double finalScore) { super(regularScore,finalScore);//将传入的finalScore值传递给父类,以便在父类中进行适当的初始化。 } @Override public double getRegularScore() { return regularScore; } @Override public double getFinalScore() { return finalScore; } @Override public double calculateTotalGrade() { double totalGrade = regularScore * 0.3 + finalScore * 0.7; return totalGrade; } } //******考察成绩,等于期末成绩******// class AssessmentScore extends Score { public AssessmentScore(double regularScore,double finalScore) { super(regularScore,finalScore); } @Override public double getRegularScore() { return regularScore; } @Override public double getFinalScore() { return finalScore; } @Override public double calculateTotalGrade() { return finalScore; } } class Classroom { private String classNumber; // 班级号 private ArrayList<Student> studentList; // 学生列表 public Classroom(String classNumber) { this.classNumber = classNumber; this.studentList = new ArrayList<>(); } // 获取班级号 public String getClassNumber() { return classNumber; } // 设置班级号 public void setClassNumber(String classNumber) { this.classNumber = classNumber; } // 获取学生列表 public ArrayList<Student> getStudentList() { return studentList; } public void addStudent(Student student) { studentList.add(student); } public double getAverageScore(InputClass t) { // 计算班级所有学生总成绩的平均值 double sumScores = 0; for (Student student : studentList) { double score = t.findScoreByStudentName(student.getStudentId()); sumScores += score; } return (int)Math.floor(sumScores / studentList.size()); } }
题目:
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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
输入样例1:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2
end
输出样例2:
在这里给出相应的输出。例如:
java : number of scores does not match
输入样例3:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.1
end
输出样例3:
在这里给出相应的输出。例如:
java : weight value error
输入样例4:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100
end
输出样例4:
在这里给出相应的输出。例如:
20201116 张三 86
java 86
202011 86
输入样例5:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100 80
end
输出样例5:
在这里给出相应的输出。例如:
20201116 张三 : access mode mismatch
20201116 张三 did not take any exams
java has no grades yet
202011 has no grades yet
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); Input parse_input = new Input(); O: while (true){ String message = input.nextLine(); if(message.equals("end")) //先接收一行信息 break O; parse_input.Input(message); } Output output = new Output(parse_input.getListClass(),parse_input.getListchooseCourse()); output.showStudent(parse_input.getListchooseCourse()); output.showCourse(parse_input.getListchooseCourse()); output.showClass(parse_input.getListchooseCourse()); } } //输入类 class Input{ ArrayList<chooseCourse> listchooseCourse = new ArrayList<>(); ArrayList<Classroom> listClass=new ArrayList<>(); public ArrayList<chooseCourse> getListchooseCourse() { return listchooseCourse; } public ArrayList<Classroom> getListClass() { return listClass; } public void Input(String str){ InputMatching inputMatching = new InputMatching(); int flag = inputMatching.matchingInput(str); switch (flag){ case 0: System.out.println("wrong format"); break; case 1: ExamcourseMessage(str); break; case 2: AssessmentcourseMessage(str); break; case 3: ExperientcourseMessage(str); break; case 4: gradeMessage(str); break; } } public void ExamcourseMessage(String str){ //考试类课程信息 String parts[] = str.split(" "); String courseName = parts[0]; String type = parts[1]; String testType = parts[2]; Course course = new Course(courseName,type,testType); //如果该课程信息属于考试类 if((Double.parseDouble(parts[3])+Double.parseDouble(parts[4]))!=1){ //权重值合计不为1 System.out.println(courseName + " : weight value error");} else if(checkCourseMessage(course,parts)) { if (searchCourse(courseName) == null) { //如果当前信息没有课程性质和课程的考核方式不匹配的情况 chooseCourse chooseCourse = new chooseCourse();//如果当前cs表中还没有添加这门课程,创建一个新的选课表 subGrade subGrade1 = new subGrade(0,Double.parseDouble(parts[3])); subGrade subGrade2 = new subGrade(0,Double.parseDouble(parts[4])); courseGrade courseGrade = new courseGrade(); courseGrade.addSubGrade(subGrade1); courseGrade.addSubGrade(subGrade2); chooseCourse.setCourse(course); chooseCourse.setGrade(courseGrade); listchooseCourse.add(chooseCourse); } } } public void AssessmentcourseMessage(String str){ //考察类课程信息 String parts[] = str.split(" "); String courseName = parts[0]; String type = parts[1]; String testType = parts[2]; Course course = new Course(courseName,type,testType); if(checkCourseMessage(course,parts)) { if (searchCourse(courseName) == null) { //System.out.println("666"); chooseCourse chooseCourse = new chooseCourse(); subGrade subGrade1 = new subGrade(0,1); courseGrade courseGrade = new courseGrade(); courseGrade.addSubGrade(subGrade1); chooseCourse.setCourse(course); chooseCourse.setGrade(courseGrade); listchooseCourse.add(chooseCourse); } } } //实验类课程信息 public void ExperientcourseMessage(String str){ String parts[] = str.split(" "); String courseName = parts[0]; String type = parts[1]; String testType = parts[2]; Course course = new Course(courseName,type,testType); course.setCount(Integer.parseInt(parts[3])); if(checkCourseMessage(course,parts)) { double sum = 0; int k = 4; for (int i = 0; i < course.getCount(); i++) { sum += Double.parseDouble(parts[k]); k++; }int sum0 = (int)Math.floor(sum); if (parts.length > 13 || parts.length <8) { System.out.println("wrong format"); } else if(sum0!=1){ System.out.println(courseName + " : weight value error"); } else if (searchCourse(courseName) == null) { chooseCourse chooseCourse = new chooseCourse(); subGrade[] subGrades = new subGrade[9]; for (int i = 0; i < course.getCount(); i++) { subGrades[i] = new subGrade(0,Double.parseDouble(parts[4+i])); } courseGrade courseGrade = new courseGrade(); for (int i = 0; i < course.getCount(); i++) {//将分项成绩组合进课程成绩 courseGrade.addSubGrade(subGrades[i]); } chooseCourse.setCourse(course);//往此次选课类中添加课程与成绩(只有权重) chooseCourse.setGrade(courseGrade); listchooseCourse.add(chooseCourse);//将该次选课添加进选课动态数组中 } } } public void gradeMessage(String str){ InputMatching inputMatching = new InputMatching(); String parts[]=str.split(" "); String stuId= parts[0];//学生学号 String classID= parts[0].substring(0,6); String name=parts[1];//学生姓名 String courseName=parts[2];//课程名字 Student student = new Student(name,stuId); if(searchClassroom(classID)==null){//如果该班级第一次出现 Classroom classroom=new Classroom(classID); listClass.add(classroom); if(searchClassroom(classID,stuId) == null){//如果该班级还没有这个学号的学生 searchClassroom(classID).addStudent(student); } }else {//如果该班级不是第一次出现 if(searchClassroom(classID,stuId) == null){ searchClassroom(classID).addStudent(student);} } Course course = searchCourse(courseName);//找到该门课程,创建一个course courseGrade courseGrade = new courseGrade(); chooseCourse chooseCourse = new chooseCourse(); //创建一个选课类 if(searchCourse(courseName)==null) {//课程是否存在 System.out.println(courseName + " " + "does not exist"); } else{ if(str.matches(inputMatching.scoreInput2)){ //学号0+姓名1+课程名称2+平时成绩3+期末成绩4 //如果符合考试的成绩信息,创建两个分项成绩类,一个课程成绩类 subGrade[] subGrades = new subGrade[2]; int i = 0; for(subGrade s : searchsubGrade(courseName)){ //找到该门课程对应的分项成绩 subGrades[i] = new subGrade(Integer.parseInt(parts[3+i]),s.getWeight()); //把存好的分项成绩添加到课程成绩中 courseGrade.addSubGrade(subGrades[i]); i++; } chooseCourse.setCourse(course); } else if (str.matches(inputMatching.scoreInput1)&&searchCourse(courseName).getTestType().equals("考察")) { //如果符合考察的成绩信息,创建一个分项成绩类,一个课程成绩类 for(subGrade s : searchsubGrade(courseName)){//学号0+姓名1+课程名称2+期末成绩3 subGrade subGrade = new subGrade(Integer.parseInt(parts[3]),s.getWeight()); //找到该门课程对应的分项成绩 courseGrade.addSubGrade(subGrade); //把存好的分项成绩添加到课程成绩中 } chooseCourse.setCourse(course); } else if (str.matches(inputMatching.scoreInput3)) { //如果符合实验的成绩信息,创建n个分项成绩类,一个课程成绩类 //学号0+姓名1+课程名称2+分项成绩3+分项成绩4... //如果输入的分数项与实际不匹配 //System.out.println(parts.length+"66"); if((searchsubGrade(courseName).size()+3) != parts.length) System.out.println(stuId + " " + name + " : access mode mismatch"); else{ subGrade[] subGrades = new subGrade[9]; int i = 0; for(subGrade s : searchsubGrade(courseName)){ //找到该门课程对应的分项成绩 subGrades[i] = new subGrade(Integer.parseInt(parts[3+i]),s.getWeight()); //把存好的分项成绩添加到课程成绩中 courseGrade.addSubGrade(subGrades[i]); i++; }chooseCourse.setCourse(course); } }else { System.out.println(stuId + " " + name + " : access mode mismatch"); } } //往此次选课类中添加课程与学生与成绩(有分数以及权重) chooseCourse.setStudent(student); chooseCourse.setGrade(courseGrade); listchooseCourse.add(chooseCourse); } public Classroom searchClassroom(String classID){//找当前班级表中是否存在该班级 for (Classroom c : listClass) { if(c.getClassNumber().equals(classID)) return c; }return null; } public Student searchClassroom(String classID,String stuID){//找当前班级表中是否存在该学生 for (Student s : searchClassroom(classID).getStudents()) { if(s.getId().equals(stuID)) return s; } return null; } //找当前选课表中是否存在该课程 public Course searchCourse(String courseName){ for(chooseCourse cs: listchooseCourse){ if(cs.getCourse().getCourseName().equals(courseName)) return cs.getCourse(); }return null; } //找当前选课表中该课程对应的分项成绩表 public ArrayList<subGrade> searchsubGrade(String courseName){ for(chooseCourse cs: listchooseCourse){ if(cs.getCourse().getCourseName().equals(courseName)) return cs.getGrade().getSubGrades(); }return null; } public boolean checkCourseMessage(Course course,String parts[]){ if(course.getType().equals("必修")&&!course.getTestType().equals("考试")){ System.out.println(course.getCourseName() + " : course type & access mode mismatch"); return false; } else if (course.getType().equals("实验")&&!course.getTestType().equals("实验")) { System.out.println(course.getCourseName() + " : course type & access mode mismatch"); return false; } else if (!course.getType().equals("实验")&&course.getTestType().equals("实验")) { System.out.println(course.getCourseName() + " : course type & access mode mismatch"); return false; } else if (course.getType().equals("实验")&&course.getTestType().equals("实验")) { if((Integer.parseInt(parts[3])+4) != parts.length){ System.out.println(course.getCourseName() + " : number of scores does not match"); return false; } } return true; } // 添加班级 public void addClass(Classroom classroom) { listClass.add(classroom); } // 添加选课 public void addchooseCourse(chooseCourse course) { listchooseCourse.add(course); } } class InputMatching {//正则表达式匹配 String stuNumMatching = "[0-9]{8}";//8个0-9的数字 String num = "[0-9]"; String weightMatching = "([0-9]+(\\.[0-9]+)?)"; String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String scoreMatching = "(?:100|[1-9]\\d?|0)"; String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String courseTypeMatching = "(选修|必修|实验)"; String checkCourseTypeMatching = "(考试|考察|实验)"; //ExamcourseInput用于定义考试课程信息模式(正则表达式) String ExamcourseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching +" " +weightMatching + " " + weightMatching; //AssessmentcourseInput用于定义考察课程信息模式(正则表达式) String AssessmentcourseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //ExamcourseInput用于定义实验课程信息模式(正则表达式) String ExperientcourseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching + " " + "\\d+(\\.\\d+)?( \\d+(\\.\\d+)?)*"; //scoreInput用于定义成绩信息模式(正则表达式) String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; String scoreInput2= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " +scoreMatching; String scoreInput3= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + "(?:" + scoreMatching + "\\s*){2,20}"; public InputMatching() { } public int matchingInput(String s) { switch (matchingCourse(s)){ //如果匹配出是课程信息,返回1 case 1: return 1; case 2: return 2; case 3: return 3; } switch (matchingScore(s)){//如果匹配出是成绩信息,返回2 case 4: return 4; } return 0; //都不是,返回0 } private int matchingCourse(String s) {//课程信息 if(s.matches(ExamcourseInput))//如果输入的信息符合考试课程信息模式 return 1; else if (s.matches(AssessmentcourseInput))//如果输入的信息符合考察课程信息模式 return 2; //如果输入的信息符合实验课程信息模式 else if (s.matches(ExperientcourseInput)) { return 3; } return 0; } //成绩信息 private int matchingScore(String s) { //System.out.println(match); if(s.matches(scoreInput1)||s.matches(scoreInput2)||s.matches(scoreInput3)) return 4; return 0; } } //输出类 class Output{ ArrayList<Student> listStudent; ArrayList<Course> listCourse; ArrayList<Classroom> listClassroom; ArrayList<chooseCourse> listchooseCourse; public Output(ArrayList<Classroom> listClassroom,ArrayList<chooseCourse> listchooseCourse){ this.listStudent = new ArrayList<>(); this.listCourse = new ArrayList<>(); this.listClassroom = listClassroom; this.listchooseCourse = listchooseCourse; } public void showStudent(ArrayList<chooseCourse> listchooseCourse){ //计算每个学生所修的全部课程总成绩以及数量 for(chooseCourse cs : listchooseCourse){//遍历选课表 if(cs.getStudent()!=null && cs.getGrade()!=null){//找到cs表含学生且含成绩的cs // System.out.println("notice!"+cs.getCourse().getCourseName()); //如果学生表动态数组中尚无该学生 if(searchStudent(cs.getStudent().getId()) == null){ Student s = new Student(cs.getStudent().getStuName(),cs.getStudent().getId());//往动态数组中添加该学生 cs.getGrade().calculateSumGrade();//先计算该学生该门课程的成绩 s.setSumGrade(cs.getGrade().getSumGrade());//再将该门成绩累加进该学生的总成绩中 s.setCount(1);//该学生的成绩数目加1 addStudent(s); }else{ //如果学生表动态数组中已存在该学生 //先计算该学生该门课程的成绩 cs.getGrade().calculateSumGrade(); //再将该门成绩累加进该学生的总成绩中 searchStudent(cs.getStudent().getId()).setSumGrade((int)Math.floor(cs.getGrade().getSumGrade())); //该学生的成绩数目加1 searchStudent(cs.getStudent().getId()).setCount(1); } } } //结合自定义的比较器(Comparator)来对学生对象按照 id 顺序进行排序。 Collections.sort(listStudent, new Comparator<Student>() { public int compare(Student student1, Student student2) { return Integer.compare(Integer.parseInt(student1.getId()), Integer.parseInt(student2.getId())); } }); for (Student student : listStudent) { int grade = (int)Math.floor(student.getSumGrade()/student.getCount()); if(grade == 0) System.out.println(student.getId() + " " +student.getStuName() + " did not take any exams"); else System.out.println(student.getId() + " " +student.getStuName() + " " + grade); } } public void showCourse(ArrayList<chooseCourse> listchooseCourse){ //单门课程的总成绩平均分 for(chooseCourse cs : listchooseCourse){ //遍历选课表 if(cs.getCourse()!=null && cs.getGrade()!=null){//找到cs表含课程且含成绩的cs //System.out.println("notice!"+cs.getStudent().getStuName()); if(searchCourse(cs.getCourse().getCourseName()) == null){ //如果课程表动态数组中尚无该课程 //往动态数组中添加该学生 Course c = new Course(cs.getCourse().getCourseName(),cs.getCourse().getType(),cs.getCourse().getTestType()); cs.getGrade().calculateSumGrade(); //先计算该学生该门课程的成绩 c.setSumGrade(cs.getGrade().getSumGrade());//再将该门成绩累加进该课程的总成绩中 c.setCount(1);//该课程的成绩数目加1 addCourse(c); }else{//如果课程表动态数组中已存在该课程 //先计算当前学生该门课程的成绩 cs.getGrade().calculateSumGrade(); //再将该门成绩累加进该课程的总成绩中 searchCourse(cs.getCourse().getCourseName()).setSumGrade((int)Math.floor(cs.getGrade().getSumGrade())); searchCourse(cs.getCourse().getCourseName()).setCounts(1); //该课程的成绩数目加1 } } } //根据courseName的字符顺序对listCourse的动态数组进行排序 Collections.sort(listCourse, new Comparator<Course>() { public int compare(Course course1, Course course2) { return course1.getCourseName().compareTo(course2.getCourseName()); } }); for (Course course : listCourse) { int grade = (int)Math.floor(course.getSumGrade()/course.getCounts()); if(grade == 0) System.out.println(course.getCourseName() + " has no grades yet"); else System.out.println(course.getCourseName() + " " + grade); } } public void showClass(ArrayList<chooseCourse> listchooseCourse){ //单个班级的总成绩平均分 for(chooseCourse cs : listchooseCourse){ if(cs.getStudent()!=null && cs.getGrade()!=null&& cs.getCourse()!=null){ //找到cs表含学生且含成绩的cs //如果班级表动态数组中尚无该学生学号所在的班级 if(searchStudent_in_Class(cs.getStudent().getId()) == null){ String classID = cs.getStudent().getId().substring(0,6);//往动态数组中添加该班级 Classroom c = new Classroom(classID); c.addStudent(cs.getStudent()); cs.getGrade().calculateSumGrade();//先计算该学生该门课程的成绩 c.setSum(cs.getGrade().getSumGrade());//再将该门成绩累加进该班级的总成绩中 c.setCount(1);//该班级所含的的成绩数目加1 addClassroom(c); }else{ cs.getGrade().calculateSumGrade();//如果学生表动态数组中已存在该学生 //先计算该学生该门课程的成绩 //再将该门成绩累加进该班级的总成绩中 searchStudent_in_Class(cs.getStudent().getId()).setSum((int)Math.floor(cs.getGrade().getSumGrade())); searchStudent_in_Class(cs.getStudent().getId()).setCount(1);//该班级的成绩数目加1 } } } Collections.sort(listClassroom, new Comparator<Classroom>() { //结合自定义的比较器(Comparator)来对学生对象按照 id 顺序进行排序。 public int compare(Classroom c1, Classroom c2) { return Integer.compare(Integer.parseInt(c1.getClassNumber()), Integer.parseInt(c2.getClassNumber())); } }); for (Classroom classroom : listClassroom) { //System.out.println(classroom.getClassNumber()+" "+classroom.getSum()+" "+classroom.getCount()); int grade = (int)Math.floor(classroom.getSum()/classroom.getCount()); if(grade == 0) System.out.println(classroom.getClassNumber() + " has no grades yet"); else System.out.println(classroom.getClassNumber() + " " + grade); } } public void addStudent(Student student) { listStudent.add(student); } public void addClassroom(Classroom classroom) { listClassroom.add(classroom); } public void addCourse(Course course) { listCourse.add(course); } public ArrayList<Student> getListStudent() { return listStudent; } public ArrayList<Course> getListCourse() { return listCourse; } public Student searchStudent(String stuID){ //根据学号找当前动态数组中是否有该学生 for(Student s : listStudent){ if(s.getId().equals(stuID)) return s; }return null; } public Course searchCourse(String courseName){//根据课程名找当前动态数组中是否有该课程 for(Course c : listCourse){ if(c.getCourseName().equals(courseName)) return c; }return null; } public Classroom searchStudent_in_Class(String stuID){//根据学号找当前动态数组中是否有该班级,有的话返回该班级 String classID = stuID.substring(0,6); for(Classroom c : listClassroom){ if(c.getClassNumber().equals(classID)) return c; }return null; } } class Classroom{//班级类 private String classNumber; // 班级号 private ArrayList<Student> students; // 学生列表 private double sum;//暂存当前班级所含的学生总成绩 private int count;//暂存该班级包含的成绩数量 public Classroom(String classNumber) { this.classNumber = classNumber; this.students = new ArrayList<>(); } public int getCount() { return count; } public void setCount(int count) { this.count += count; } public String getClassNumber() { return classNumber; } public void setClassNumber(String classNumber) { this.classNumber = classNumber; } public double getSum() { return sum; } public void setSum(double sum) { this.sum += sum; } public ArrayList<Student> getStudents() { return students; } public void addStudent(Student student) { boolean flag = false; for(Student s : students){ if(s == student){ flag = true; } }if(flag == false) students.add(student); } } //选课类 class chooseCourse { private Course course; private Student student; private courseGrade grade; public chooseCourse() { } public Course getCourse() { // Getter方法 return course; } public Student getStudent() { return student; } public courseGrade getGrade() { return grade; } public void setCourse(Course course) { // Setter方法 this.course = course; } public void setStudent(Student student) { this.student = student; } public void setGrade(courseGrade grade) { this.grade = grade; } } class Student {//学生类 private String stuName; // 学生姓名 private String id; // 学生ID private int count;//存一下该学生选的总课数 private double sumGrade;//存一下该学生的平均总成绩 public Student(String stuName,String id){ this.stuName = stuName; this.id = id; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getId() { return id; } public void setId(String id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count += count; } public double getSumGrade() { return sumGrade; } public void setSumGrade(double Grade) { this.sumGrade += Grade; } } //课程类 class Course{ String courseName; String type; String testType; private double sumGrade; //暂存该课程的总成绩 private int counts;//暂存该课程当前成绩的数目 private int count;//只针对实验课的分项成绩数量 public Course(String courseName,String type,String testType) { this.courseName=courseName; this.type=type; this.testType=testType; } public String getCourseName(){ return courseName; } public String getType(){ return type; } public String getTestType() { return testType; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getSumGrade() { return sumGrade; } public int getCounts() { return counts; } public void setSumGrade(double Grade) { this.sumGrade += Grade; } public void setCounts(int counts) { this.counts += counts; } } //课程成绩类 class courseGrade{ private double sumGrade; //总成绩 private ArrayList<subGrade> subGrades; // 存储成绩分项列表 public courseGrade(){ subGrades = new ArrayList<>(); } // 获取总成绩 public double getSumGrade() { return sumGrade; } // 添加一个SubGrade对象到动态列表 public void addSubGrade(subGrade subGrade) { subGrades.add(subGrade); } // 获取成绩分项列表 public ArrayList<subGrade> getSubGrades() { return subGrades; } // 计算总成绩 public void calculateSumGrade() { float totalScore = 0; for (subGrade s : subGrades) { totalScore += s.getGrade() * s.getWeight(); } this.sumGrade = totalScore ; } } class subGrade { private double grade; // 成绩分值 private double weight; // 折算权重 public subGrade(double grade, double weight) { this.grade = grade; this.weight = weight; } public double getGrade() { return grade; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public void setGrade(double grade) { this.grade = this.grade; } }
代码类图:
(截的图似乎不太清楚)
三、踩坑心得
这次迭代最大的问题就是我前两次搭框架时总想着赶紧写完就好,而不管后期添加功能的不规范性,导致每一次都需要重写框架。直到最后一次才写出较为满意的框架。还有就是课程2中,使用了很多哈希表,我本身对哈希表掌握的不好,其实每次代码量一上来都糊里糊涂,逻辑衔接容易断。而直接使用普通的动态数组其实更为便捷,下次编写代码时,应提前规划设计好各类信息的存储方式,降低代码复杂度。
四、改进建议
成绩三的更迭中,对时间复杂度掌握不清晰,由于我使用的存储方式是哈希表这些,导致我使用时不是很清楚,输出表运用的不熟练,下次同类型题,改用动态数组即可,或者再多学学哈希表,争取掌握得更熟练些。
还有就是输入信息的判断类,可以利用工厂模式再优化。
五、总结
这三次作业的成绩更迭中,我在开发过程中遇到了一些问题。首先,最初的代码框架没有建立清晰的任务分割。后来学习了工厂模式等设计模式的知识,希望在下次类似作业中能够应用,避免这种情况的发生。其次,由于我使用的存储方式是哈希表而不是动态数组等,而我其实不太擅长哈希表,导致我对代码每次要重读很久去理解。
总的来说,这次作业让我巩固了类的封装设计、方法重载、类的继承以及正则表达式等相关知识。在写作业的过程中,我也踩过一些坑,但通过请教老师和同学以及查阅相关资料,我不断进步并从中获得了宝贵的经验。对于期末考试,我意识到自己在接口方面的理解以及一些模式的掌握还不够牢固,需要加强基础理论的学习与巩固。总的来说,我会继续努力改进,提升自己的编程能力。
标签:return,String,double,PTA,blog,课程,集及,成绩,public
From: https://www.cnblogs.com/1627271667lk/p/17891900.html