OOP作业总结三
一、前言
本次作业主要复习了之前学的类的设计,以及多态和接口的使用,同时也考察了哈希集和树集的掌握程度,并且也运用到了一些正则表达式。在第三阶段的作业中,前几次作业的难度都不是特别大,后几次作业的难度有了一定的提升。题目量都不是特别大,但还是需要花费时间,认真去做。特别是后三次作业中出现的统计成绩,迭代了三次,这考察了我们所写的代码的复用性和可移植性,如果一开始代码逻辑设计不合理,则会导致后续作业难以完成,很遗憾我在一开始代码设计的不是很合理,导致最后一次统计成绩没能迭代成功。
二、设计与分析
1.统计Java程序中关键词的出现次数(题目集9的7-1)
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit
行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format
- 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
本题考查了对哈希集和树集,以及正则表达式的运用。我首先定义了一个关键字列表,包含了Java中的所有关键字。然后,我们使用循环读取从键盘输入的源码,将其存储在StringBuilder对象中。接下来,我们使用一个Map对象来记录每个关键字出现的次数。遍历关键字列表,通过在源码中搜索每个关键字并进行计数。在搜索关键字时,我们还需要检查该关键字是否在注释或字符串中,以排除不应计入统计的情况。最后,我们按照关键字的升序对计数结果进行排序,并将结果输出。判断指定位置的字符是否在注释或字符串中则是通过使用正则表达式或其他方法来完成这一判断。
类图

import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); StringBuilder sb = new StringBuilder(); String line; while (true) { line = scanner.nextLine(); if (line.equals("exit")) { break; } sb.append(line).append("\n"); } String javaSourceCode = sb.toString().trim(); // 删去字符串 javaSourceCode = javaSourceCode.replaceAll("\".*\"", " "); // 删去单行注释 javaSourceCode = javaSourceCode.replaceAll("//.*\n"," "); // 删去多行注释 javaSourceCode = javaSourceCode.replaceAll("/\\*(.|\n)*?\\*/"," "); // 替换等号 javaSourceCode = javaSourceCode.replaceAll("=", "A"); // 删去无关的字符 //javaSourceCode = javaSourceCode.replaceAll("[^a-zA-Z]", " "); // 将多个空格替换为单个空格以便分割 javaSourceCode = javaSourceCode.replaceAll(" +", " "); if (javaSourceCode.isEmpty()) { System.out.println("Wrong Format"); return; } Map<String, Integer> keywordCountMap = countKeywords(javaSourceCode); List<Map.Entry<String, Integer>> keywordCountList = new ArrayList<>(keywordCountMap.entrySet()); Collections.sort(keywordCountList, (e1, e2) -> e1.getKey().compareTo(e2.getKey())); for (Map.Entry<String, Integer> entry : keywordCountList) { System.out.println(entry.getValue() + "\t" +entry.getKey()); } } private static Map<String, Integer> countKeywords(String javaSourceCode) { Set<String> keywords = new HashSet<>(Arrays.asList( "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "for", "final", "finally", "float", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while", "true", "false", "null" )); Map<String, Integer> keywordCountMap = new TreeMap<>(); String[] lines = javaSourceCode.split("\n"); for (String line : lines) { line = line.trim(); if (line.startsWith("//")) { continue; } String[] words = line.split("\\W+"); for (String word : words) { if (word.startsWith("\"") && word.endsWith("\"")) { continue; } if (keywords.contains(word)) { keywordCountMap.put(word, keywordCountMap.getOrDefault(word, 0) + 1); } } } return keywordCountMap; } }
2.课程成绩统计程序-1(题目集10的7-1)
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修
考核方式输入选项:考试、考察
课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
以上信息的相关约束:
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)成绩平均分只取整数部分,小数部分丢弃
本题主要设计了三个类:Student,
Grade和Course
。
Student
类表示学生,包含学号(studentId)、姓名(name)和成绩(grades)。成绩使用一个Map
来存储,键为课程名称,值为成绩列表。addGrade
方法用于向指定课程添加成绩,如果该课程还不存在,则先创建一个空的成绩列表。getAverageGrade
方法用于计算学生的平均成绩,遍历所有课程的成绩列表,累加成绩并计算平均值。
Grade
类用于分析成绩信息。它包含一个学生列表(students)、课程平均分的映射(courseAverages)和班级平均分的映射(classAverages)。addGrades
方法接受一个字符串列表作为输入,按行遍历每个输入字符串。对于每个输入,首先将其拆分为学号、姓名、课程和成绩四个部分。然后调用getStudent
方法查找或创建对应的学生对象,将课程和成绩添加到学生的成绩列表中,并更新课程平均分的映射。最后调用getAverages
方法计算各种平均分并输出结果。
addStudent
方法用于根据学号查找学生对象,如果找到了对应的学生,则返回该学生对象;如果没有找到,则创建一个新的学生对象,并将其添加到学生列表中。
getAverages
方法用于计算各种平均分并输出结果。首先遍历课程平均分的映射,计算每门课程的平均分并更新映射。然后遍历学生列表,对每个学生调用getAverageGrade
方法获取平均成绩,如果平均成绩为0,则输出该学生没有参加考试的信息;否则输出学生的学号、姓名和平均成绩。最后遍历班级平均分的映射,按班级号排序并输出平均分。
在main
方法中,我们提供了一个示例输入(包含6条成绩记录),创建一个Grade
对象并调用getGrades
方法进行分析和输出结果。
这段代码的主要思路是通过创建Student
对象来表示学生,并使用Map
来存储成绩信息。使用Grade
类来分析成绩信息并计算各种平均分。这题中存在一些测试点极其难过,为了通过这些测试点,代码改了又改,所以可复用性和移植性极差,即便如此还是有些测试点没过,导致后续迭代也出现相关问题。
参考类图
复杂度

import java.text.Collator; import java.util.*; public class Main { // private static List<Course> courses = new ArrayList<>(); // 存储成绩信息的List,每个元素为Grade对象 private static Map<String, Course> courses = new TreeMap<>(); // 存储成绩信息的List,每个元素为Grade对象 private static List<Grade> grades = new ArrayList<>(); public static void main(String[] args) { //Scanner scanner = new Scanner(System.in); int flag = 0; Scanner scanner = new Scanner(System.in); StringBuilder sb = new StringBuilder(); String line; while (true) { line = scanner.nextLine(); if (line.equals("end")) { break; } sb.append(line).append("\n"); } String[] st = sb.toString().split("\n"); // 解析输入的数据 for (String a:st) { String[] data = a.split(" "); for (String s : data) { if (s.isEmpty() || s.contains(" ")) { System.out.println("wrong format"); flag = 1; continue; } } if(flag ==0){ if (data.length >= 2 && data.length <= 3) { // 课程信息 if (data[0].length() > 10) { System.out.println("wrong format"); } else if (data[0].length() > 0 && data[0].length() <= 10){ if ((data[1].equals("必修") || data[1].equals("选修"))) { if (data.length == 3) { if (data[2].equals("考试") || data[2].equals("考察")) { String courseName = data[0]; String courseType = data[1]; String accessMode = data[2]; addCourse(courseName, courseType, accessMode); } else { System.out.println("wrong format"); } } else if (data.length == 2) { String courseName = data[0]; String courseType = data[1]; addCourse(courseName, courseType, "考试"); } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else if (data.length >=4 && data.length <= 5) { // 成绩信息 if (data[0].length() != 8) { System.out.println("wrong format"); } else if (courses.keySet().contains(data[2])){ String studentID = data[0]; String studentName = data[1]; String courseName = data[2]; String regex = "^\\d{1,2}$|^100$"; // 匹配0-100的数 // int dailyGrade = data[3].equals("") ? -1 : Integer.parseInt(data[3]); if (data.length == 4) { int dailyGrade = -1; if(data[3].matches(regex)){ int finalGrade = Integer.parseInt(data[3]); addGrade(studentID, studentName, courseName, -1, finalGrade); } else { System.out.println("wrong format"); } } else if (data.length == 5){ if(data[3].matches(regex)){ int dailyGrade = Integer.parseInt(data[3]); int finalGrade = Integer.parseInt(data[4]); addGrade(studentID, studentName, courseName, dailyGrade, finalGrade); } else { System.out.println("wrong format"); } }else { System.out.println(data[2] + " does not exist"); } }else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } } // 输出结果 outputStudentGradeAverage(); outputCourseGradeAverage(); outputClassGradeAverage(); } /** * 添加课程信息 */ /** * 添加课程信息 */ private static void addCourse(String courseName, String courseType, String accessMode) { if (courses.containsKey(courseName)) { // 已经存在该课程,忽略本次输入 // return; }else { boolean isExam = "考试".equals(accessMode); boolean isRequired = "必修".equals(courseType); if (isRequired && !isExam) { System.out.println(courseName + " : course type & access mode mismatch"); } Course course = new Course(courseName, isRequired, isExam); courses.put(courseName, course); } } /** * 添加成绩信息 */ private static void addGrade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade) { // if (!courses.containsKey(courseName)) int flag1 = 0; for(int i = 0; i < courses.get(courseName).getGrades().size(); i++) { if (courses.get(courseName).getGrades().get(i).getStudentID().equals(studentID)){ flag1 = 1; break; } } if(flag1 == 0) { if ((!courses.get(courseName).isExam() && courses.get(courseName).isRequired())) { // 课程不存在,输出错误信息 System.out.println(courseName + " does not exist"); } Course course = courses.get(courseName); if ((dailyGrade == -1) == course.isExam()) { // 成绩数量和考核方式不匹配,输出错误信息 System.out.println(studentID + " " + studentName + " : access mode mismatch"); // return; finalGrade = -1; } if (!course.isExam() && course.isRequired()) { finalGrade = -1; } //if (!course.isExam() &&) if (finalGrade > 100 || dailyGrade > 100 ) { dailyGrade = -1; finalGrade = -2; System.out.println("wrong format"); } else { Grade grade = new Grade(studentID, studentName, courseName, dailyGrade, finalGrade); grades.add(grade); courses.get(courseName).addGrade(grade); } } } /** * 输出学生所有课程总成绩的平均分 */ private static void outputStudentGradeAverage() { // 将grades按学号从小到大排序 Collections.sort(grades, Comparator.comparing(Grade::getStudentID)); // 使用TreeMap保存学生信息并排序 Map<String, Student> students = new TreeMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); if (!students.containsKey(studentID)) { students.put(studentID, new Student(studentID, grade.getStudentName())); } Student student = students.get(studentID); student.addGrade(grade); } // 遍历并输出每个学生的平均分 for (String studentID : students.keySet()) { Student student = students.get(studentID); double averageGrade = student.getAverageGrade(); if (averageGrade == -1) { System.out.println(studentID + " " + student.getStudentName() + " did not take any exams"); } else { System.out.println(studentID + " " + student.getStudentName() + " " + (int) averageGrade); } } } /** * 输出单门课程成绩平均分 */ private static void outputCourseGradeAverage() { // List<String> courseNames = new ArrayList<>(courses.keySet()); // // 按课程名称的字母顺序排序 // Collections.sort(courseNames, String.CASE_INSENSITIVE_ORDER); List<String> courseNames = new ArrayList<>(courses.keySet()); // 使用 Collator 比较字符串的大小,实现按照汉字字母顺序排序 Collator collator = Collator.getInstance(Locale.CHINA); Collections.sort(courseNames, collator::compare); for (String courseName : courseNames) { Course course = courses.get(courseName); if(!grades.isEmpty()){ for(int i=0;i<grades.size();i++) course.addGrade(grades.get(i)); } if(!course.isExam() && course.isRequired()) { }else{ if (course.isExam()) { // 考试课程,需要计算平时成绩和总成绩平均分 double dailyAverage = course.getDailyAverage(); double finalAverage = course.getFinalAverage(); double totalAverage = course.getTotalAverage(); // if (Double.isNaN(dailyAverage) && Double.isNaN(finalAverage) && Double.isNaN(totalAverage)) if(totalAverage == -1||totalAverage == 0) { System.out.println(courseName + " has no grades yet"); } else { System.out.println(courseName + " " + (int) dailyAverage + " " + (int) finalAverage + " " + (int) totalAverage); } } else { // 考察课程,只需要计算期末成绩平均分 double finalAverage = course.getFinalAverage(); if (finalAverage == -1) { System.out.println(courseName + " has no grades yet"); } else { System.out.println(courseName + " " + (int) finalAverage + " " + (int) finalAverage); } } } } } /** * 输出班级所有课程总成绩平均分 */ private static void outputClassGradeAverage() { Map<String, List<Grade>> classGrades = new HashMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); String classID = studentID.substring(0, 6); if (!classGrades.containsKey(classID)) { classGrades.put(classID, new ArrayList<>()); } classGrades.get(classID).add(grade); } List<String> classIDs = new ArrayList<>(classGrades.keySet()); // 按班级号从小到大排序 Collections.sort(classIDs); for (String classID : classIDs) { List<Grade> classGradeList = classGrades.get(classID); double totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : classGradeList) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeSum == -1) { System.out.println(classID + " has no grades yet"); } else { double totalAverageGrade = totalGradeSum / totalGradeCount; System.out.println(classID + " " + (int) totalAverageGrade); } } } } class Course { String courseName; // 课程名称 boolean isRequired; // 是否必修 boolean isExam; // 是否考试 List<Grade> grades = new ArrayList<>(); // 成绩列表 public Course(String courseName, boolean isRequired, boolean isExam) { this.courseName = courseName; this.isRequired = isRequired; this.isExam = isExam; } public boolean isExam() { return isExam; } public boolean isRequired() { return isRequired; } /** * 添加成绩到该课程 */ public void addGrade(Grade grade) { if (grade.getCourseName().equals(courseName)) { grades.add(grade); } } /** * 计算平时成绩平均分 */ public double getDailyAverage() { int dailyGradeSum = 0; int dailyGradeCount = 0; for (Grade grade : grades) { int dailyGrade = grade.getDailyGrade(); if (dailyGrade != -1) { dailyGradeSum += dailyGrade; dailyGradeCount++; } } if (dailyGradeCount == 0) { return 0; } return (double) dailyGradeSum / dailyGradeCount; } /** * 计算期末成绩平均分 */ public double getFinalAverage() { int finalGradeSum = 0; int finalGradeCount = 0; for (Grade grade : grades) { int finalGrade = grade.getFinalGrade(); finalGradeSum += finalGrade; finalGradeCount++; } if (finalGradeCount == 0) { return -1; } return (double) finalGradeSum / finalGradeCount; } /** * 计算总成绩平均分 */ public double getTotalAverage() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return 0; } return (double) totalGradeSum / totalGradeCount; } public List<Grade> getGrades(){ return grades; } } class Grade { private String studentID; // 学号 private String studentName; // 姓名 private String courseName; // 课程名称 private int dailyGrade; // 平时成绩,如果没有则为-1 private int finalGrade; // 期末成绩 public Grade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade) { this.studentID = studentID; this.studentName = studentName; this.courseName = courseName; this.dailyGrade = dailyGrade; this.finalGrade = finalGrade; } public String getStudentID() { return studentID; } public String getStudentName() { return studentName; } public String getCourseName() { return courseName; } public int getDailyGrade() { return dailyGrade; } public int getFinalGrade() { return finalGrade; } /** * 计算总成绩 */ public double getTotalGrade() { if (dailyGrade == -1) { return finalGrade; } else if (finalGrade == -1){ return finalGrade; } else { return dailyGrade * 0.3 + finalGrade * 0.7; } } // @Override // public int compareTo(Grade other) { // // 按照学号从小到大排序 // return this.studentID.compareTo(other.getStudentID()); // } } class Student { private List<Grade> grades = new ArrayList<>(); // 成绩列表 private String studentID; // 学号 private String studentName; // 姓名 public Student(String studentID, String studentName) { this.studentID = studentID; this.studentName = studentName; } public String getStudentId() { return studentID; } public void setStudentId(String studentId) { this.studentID = studentId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public void addGrade(Grade grade) { if (grade.getStudentID().equals(studentID)) { grades.add(grade); } } /** * 计算该学生所有课程的总成绩平均分 */ public double getAverageGrade() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return -1; } else { return (double) totalGradeSum / totalGradeCount; } } }
3.课程成绩统计程序-2(题目集11的7-3)
课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,
要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。
题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)
课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。
考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重
考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重
实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。
学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
单门课程成绩按课程名称的字符顺序输出
课程成绩输出格式:课程名称+英文空格+总成绩平均分
6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"
7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"
本题在上题的基础上加了一个实验,实验的成绩是按权重进行计算,只需在Grade类中加入相关计算方法,并在Student类里添加实验课程的相关方法即可。
首先Student
方法中,我们可以添加一个参数,用于传递当前正在解析的课程名称。然后,我们可以在解析分项成绩数量值和分项成绩权重的个数时,检查它们是否匹配。如果不匹配,我们可以输出相应的错误信息。
其次,在Student
方法中,我们可以添加另一个参数,用于传递当前正在解析的分项成绩权重列表。然后,我们可以在解析分项成绩权重值的总和时,检查它们是否等于1。如果不等于1,我们可以输出相应的错误信息。
类图

import java.text.Collator; import java.util.*; public class Main { // 存储成绩信息的List,每个元素为Grade对象 private static Map<String, Course> courses = new TreeMap<>(); // 存储成绩信息的List,每个元素为Grade对象 private static List<Grade> grades = new ArrayList<>(); public static void main(String[] args) { int flag = 0; Scanner scanner = new Scanner(System.in); StringBuilder sb = new StringBuilder(); String line; while (true) { line = scanner.nextLine(); if (line.equals("end")) { break; } sb.append(line).append("\n"); } String[] st = sb.toString().split("\n"); // 解析输入的数据 for (String a:st) { String[] data = a.split(" "); for (String s : data) { if (s.isEmpty() || s.contains(" ")) { System.out.println("wrong format"); flag = 1; } } if(flag ==0){ if (data.length >= 2 && data.length <= 3) { // 课程信息 if (data[0].length() > 10) { System.out.println("wrong format"); } else if (data[0].length() > 0 && data[0].length() <= 10){ if ((data[1].equals("必修") || data[1].equals("选修") || data[2].equals("实验"))) { if (data.length == 3) { if (data[2].equals("考试") || data[2].equals("考察") || data[2].equals("实验")) { String courseName = data[0]; String courseType = data[1]; String accessMode = data[2]; addCourse(courseName, courseType, accessMode); } else { System.out.println("wrong format"); } } else if (data.length == 2) { String courseName = data[0]; String courseType = data[1]; addCourse(courseName, courseType, "考试"); } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else if (data.length >=4 && data.length <= 5) { // 成绩信息 if (data[0].length() != 8) { System.out.println("wrong format"); } else if (courses.keySet().contains(data[2])){ String studentID = data[0]; String studentName = data[1]; String courseName = data[2]; String regex = "^\\d{1,2}$|^100$"; // 匹配0-100的数 if (data.length == 4) { if(data[3].matches(regex)){ int finalGrade = Integer.parseInt(data[3]); addGrade(studentID, studentName, courseName, -1, finalGrade); } else { System.out.println("wrong format"); } } else if (data.length == 5){ if(data[3].matches(regex)){ int dailyGrade = Integer.parseInt(data[3]); int finalGrade = Integer.parseInt(data[4]); addGrade(studentID, studentName, courseName, dailyGrade, finalGrade); } else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } } else if (data.length > 5 && data.length <= 13){ // 实验成绩信息 if (data[0].length() != 8) { System.out.println("wrong format"); } else if (courses.keySet().contains(data[2])){ String studentID = data[0]; String studentName = data[1]; String courseName = data[2]; String regex = "^\\d{1,2}$|^100$"; // 匹配0-100的数 if ( data[3].matches("[4-9]")) { for (int i = 4; i < data.length; i++) { if(data[i].matches(regex)) { }else{ break; } } int i; if(data[3].matches("[4-9]")){ i = Integer.parseInt(data[3]); if(i != (data.length - 4)){ addGrade(studentID, studentName, courseName, 0,100); }else{ switch (Integer.parseInt(data[3])) { case 4: int[] exGrades1 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7])}; addGrade(studentID, studentName, courseName, exGrades1); break; case 5: int[] exGrades2 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8])}; addGrade(studentID, studentName, courseName, exGrades2); break; case 6: int[] exGrades3 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9])}; addGrade(studentID, studentName, courseName, exGrades3); break; case 7: int[] exGrades4 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10])}; addGrade(studentID, studentName, courseName, exGrades4); break; case 8: int[] exGrades5 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10]), Integer.parseInt(data[11])}; addGrade(studentID, studentName, courseName, exGrades5); break; case 9: int[] exGrades6 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10]), Integer.parseInt(data[11]), Integer.parseInt(data[12])}; addGrade(studentID, studentName, courseName, exGrades6); break; default: System.out.println("wrong format"); } } } } else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } } } // 输出结果 outputStudentGradeAverage(); outputCourseGradeAverage(); outputClassGradeAverage(); } /** * 添加课程信息 */ /** * 添加课程信息 */ private static void addCourse(String courseName, String courseType, String accessMode) { if (courses.containsKey(courseName)) { }else { boolean isExam = "考试".equals(accessMode); boolean isRequired = "必修".equals(courseType); if (isRequired && !isExam) { System.out.println(courseName + " : course type & access mode mismatch"); }else{ Course course = new Course(courseName, isRequired, isExam); courses.put(courseName, course); } } } /** * 添加成绩信息 */ private static void addGrade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade) { int flag1 = 0; for(int i = 0; i < courses.get(courseName).getGrades().size(); i++) { if (courses.get(courseName).getGrades().get(i).getStudentID().equals(studentID)){ flag1 = 1; break; } } if(flag1 == 0) { if ((!courses.get(courseName).isExam() && courses.get(courseName).isRequired())) { // 课程不存在,输出错误信息 System.out.println(courseName + " does not exist"); } Course course = courses.get(courseName); if ((dailyGrade == -1) == course.isExam()) { // 成绩数量和考核方式不匹配,输出错误信息 System.out.println(studentID + " " + studentName + " : access mode mismatch"); finalGrade = -1; } if (!course.isExam() && course.isRequired()) { finalGrade = -1; } if (finalGrade > 100 || dailyGrade > 100 ) { System.out.println("wrong format"); } else { Grade grade = new Grade(studentID, studentName, courseName, dailyGrade, finalGrade,null); grades.add(grade); courses.get(courseName).addGrade(grade); } } } private static void addGrade(String studentID, String studentName, String courseName, int[] exGrades) { int flag1 = 0; for(int i = 0; i < courses.get(courseName).getGrades().size(); i++) { if (courses.get(courseName).getGrades().get(i).getStudentID().equals(studentID)){ flag1 = 1; break; } } if(flag1 == 0) { if ((!courses.get(courseName).isExam() && courses.get(courseName).isRequired())) { // 课程不存在,输出错误信息 System.out.println(courseName + " does not exist"); } Course course = courses.get(courseName); for (int i:exGrades) { if (i < 0 || i > 100) { System.out.println("wrong format"); return; } } Grade grade = new Grade(studentID, studentName, courseName, -1, -2,exGrades); grades.add(grade); courses.get(courseName).addGrade(grade); } } /** * 输出学生所有课程总成绩的平均分 */ private static void outputStudentGradeAverage() { // 将grades按学号从小到大排序 Collections.sort(grades, Comparator.comparing(Grade::getStudentID)); // 使用TreeMap保存学生信息并排序 Map<String, Student> students = new TreeMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); if (!students.containsKey(studentID)) { students.put(studentID, new Student(studentID, grade.getStudentName())); } Student student = students.get(studentID); student.addGrade(grade); } // 遍历并输出每个学生的平均分 for (String studentID : students.keySet()) { Student student = students.get(studentID); double averageGrade = student.getAverageGrade(); if (averageGrade == -1) { System.out.println(studentID + " " + student.getStudentName() + " did not take any exams"); } else { System.out.println(studentID + " " + student.getStudentName() + " " + (int) averageGrade); } } } /** * 输出单门课程成绩平均分 */ private static void outputCourseGradeAverage() { // 按课程名称的字母顺序排序 List<String> courseNames = new ArrayList<>(courses.keySet()); // 使用 Collator 比较字符串的大小,实现按照汉字字母顺序排序 Collator collator = Collator.getInstance(Locale.CHINA); Collections.sort(courseNames, collator::compare); for (String courseName : courseNames) { Course course = courses.get(courseName); if(!grades.isEmpty()){ for(int i=0;i<grades.size();i++) course.addGrade(grades.get(i)); } if(!course.isExam() && course.isRequired()) { }else{ if (course.isExam()) { // 考试课程,需要计算平时成绩和总成绩平均分 double dailyAverage = course.getDailyAverage(); double finalAverage = course.getFinalAverage(); double totalAverage = course.getTotalAverage(); if(totalAverage == -1||totalAverage == 0) { System.out.println(courseName + " has no grades yet"); } else { System.out.println(courseName + " " + (int) dailyAverage + " " + (int) finalAverage + " " + (int) totalAverage); } } else { // 考察课程,只需要计算期末成绩平均分 double finalAverage = course.getFinalAverage(); double totalAverage = course.getTotalAverage(); if (finalAverage == -1) { System.out.println(courseName + " has no grades yet"); } else if (finalAverage == -2) { System.out.println(courseName + " " + (int) totalAverage); }else { System.out.println(courseName + " " + (int) finalAverage + " " + (int) finalAverage); } } } } } /** * 输出班级所有课程总成绩平均分 */ private static void outputClassGradeAverage() { Map<String, List<Grade>> classGrades = new HashMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); String classID = studentID.substring(0, 6); if (!classGrades.containsKey(classID)) { classGrades.put(classID, new ArrayList<>()); } classGrades.get(classID).add(grade); } List<String> classIDs = new ArrayList<>(classGrades.keySet()); // 按班级号从小到大排序 Collections.sort(classIDs); for (String classID : classIDs) { List<Grade> classGradeList = classGrades.get(classID); double totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : classGradeList) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeSum == -1) { System.out.println(classID + " has no grades yet"); } else { double totalAverageGrade = totalGradeSum / totalGradeCount; System.out.println(classID + " " + (int) totalAverageGrade); } } } } class Course { String courseName; // 课程名称 boolean isRequired; // 是否必修 boolean isExam; // 是否考试 List<Grade> grades = new ArrayList<>(); // 成绩列表 public Course(String courseName, boolean isRequired, boolean isExam) { this.courseName = courseName; this.isRequired = isRequired; this.isExam = isExam; } public boolean isExam() { return isExam; } public boolean isRequired() { return isRequired; } /** * 添加成绩到该课程 */ public void addGrade(Grade grade) { if (grade.getCourseName().equals(courseName)) { grades.add(grade); } } /** * 计算平时成绩平均分 */ public double getDailyAverage() { int dailyGradeSum = 0; int dailyGradeCount = 0; for (Grade grade : grades) { int dailyGrade = grade.getDailyGrade(); if (dailyGrade != -1) { dailyGradeSum += dailyGrade; dailyGradeCount++; } } if (dailyGradeCount == 0) { return 0; } return (double) dailyGradeSum / dailyGradeCount; } /** * 计算期末成绩平均分 */ public double getFinalAverage() { int finalGradeSum = 0; int finalGradeCount = 0; for (Grade grade : grades) { int finalGrade = grade.getFinalGrade(); finalGradeSum += finalGrade; finalGradeCount++; } if (finalGradeCount == 0) { return -1; } return (double) finalGradeSum / finalGradeCount; } /** * 计算总成绩平均分 */ public double getTotalAverage() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return 0; } return (double) totalGradeSum / totalGradeCount; } public List<Grade> getGrades(){ return grades; } } class Grade { private String studentID; // 学号 private String studentName; // 姓名 private String courseName; // 课程名称 private int dailyGrade; // 平时成绩,如果没有则为-1 private int finalGrade; // 期末成绩 private int[] exGrades; // 实验成绩 public Grade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade, int[] exGrades) { this.studentID = studentID; this.studentName = studentName; this.courseName = courseName; this.dailyGrade = dailyGrade; this.finalGrade = finalGrade; this.exGrades = exGrades; } public String getStudentID() { return studentID; } public String getStudentName() { return studentName; } public String getCourseName() { return courseName; } public int getDailyGrade() { return dailyGrade; } public int getFinalGrade() { return finalGrade; } /** * 计算总成绩 */ public double getTotalGrade() { if(dailyGrade == -1 && finalGrade == -2){ int sum = 0; int count = 0; for (int i:exGrades) { sum+=i; count++; } return (int)sum / count; } else if (dailyGrade == -1) { return finalGrade; } else if (finalGrade == -1){ return finalGrade; } else { return dailyGrade * 0.3 + finalGrade * 0.7; } } } class Student { private List<Grade> grades = new ArrayList<>(); // 成绩列表 private String studentID; // 学号 private String studentName; // 姓名 public Student(String studentID, String studentName) { this.studentID = studentID; this.studentName = studentName; } public String getStudentName() { return studentName; } public void addGrade(Grade grade) { if (grade.getStudentID().equals(studentID)) { grades.add(grade); } } /** * 计算该学生所有课程的总成绩平均分 */ public double getAverageGrade() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return -1; } else { return (double) totalGradeSum / totalGradeCount; } } }
4.课程成绩统计程序-3(题目集12的7-2)
课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,
要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。
题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。
实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)
课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。
考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重
考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重
实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}
计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。
学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
单门课程成绩按课程名称的字符顺序输出
课程成绩输出格式:课程名称+英文空格+总成绩平均分
6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"
7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"
本题较上题修改了课程的权重,同时修改了计算总成绩的,并且要求修改类结构,将成绩类的继承关系改为组合关系。这大大增加了迭代难度,由于一开始代码设计的不是很合理,导致我的代码修改起来难度较大,最终也没能解决问题。
修改类图

import java.text.Collator; import java.util.*; public class Main { // 存储成绩信息的List,每个元素为Grade对象 private static Map<String, Course> courses = new TreeMap<>(); // 存储成绩信息的List,每个元素为Grade对象 private static List<Grade> grades = new ArrayList<>(); public static void main(String[] args) { int flag = 0; Scanner scanner = new Scanner(System.in); StringBuilder sb = new StringBuilder(); String line; while (true) { line = scanner.nextLine(); if (line.equals("end")) { break; } sb.append(line).append("\n"); } String[] st = sb.toString().split("\n"); // 解析输入的数据 for (String a:st) { String[] data = a.split(" "); for (String s : data) { if (s.isEmpty() || s.contains(" ")) { System.out.println("wrong format"); flag = 1; } } if(flag ==0){ if (data.length >= 2 && data.length <= 3) { // 课程信息 if (data[0].length() > 10) { System.out.println("wrong format"); } else if (data[0].length() > 0 && data[0].length() <= 10){ if ((data[1].equals("必修") || data[1].equals("选修") || data[2].equals("实验"))) { if (data.length == 3) { if (data[2].equals("考试") || data[2].equals("考察") || data[2].equals("实验")) { String courseName = data[0]; String courseType = data[1]; String accessMode = data[2]; addCourse(courseName, courseType, accessMode); } else { System.out.println("wrong format"); } } else if (data.length == 2) { String courseName = data[0]; String courseType = data[1]; addCourse(courseName, courseType, "考试"); } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else { System.out.println("wrong format"); } } else if (data.length >=4 && data.length <= 5) { // 成绩信息 if (data[0].length() != 8) { System.out.println("wrong format"); } else if (courses.keySet().contains(data[2])){ String studentID = data[0]; String studentName = data[1]; String courseName = data[2]; String regex = "^\\d{1,2}$|^100$"; // 匹配0-100的数 if (data.length == 4) { if(data[3].matches(regex)){ int finalGrade = Integer.parseInt(data[3]); addGrade(studentID, studentName, courseName, -1, finalGrade); } else { System.out.println("wrong format"); } } else if (data.length == 5){ if(data[3].matches(regex)){ int dailyGrade = Integer.parseInt(data[3]); int finalGrade = Integer.parseInt(data[4]); addGrade(studentID, studentName, courseName, dailyGrade, finalGrade); } else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } } else if (data.length > 5 && data.length <= 13){ // 实验成绩信息 if (data[0].length() != 8) { System.out.println("wrong format"); } else if (courses.keySet().contains(data[2])){ String studentID = data[0]; String studentName = data[1]; String courseName = data[2]; String regex = "^\\d{1,2}$|^100$"; // 匹配0-100的数 if ( data[3].matches("[4-9]")) { for (int i = 4; i < data.length; i++) { if(data[i].matches(regex)) { }else{ break; } } int i; if(data[3].matches("[4-9]")){ i = Integer.parseInt(data[3]); if(i != (data.length - 4)){ addGrade(studentID, studentName, courseName, 0,100); }else{ switch (Integer.parseInt(data[3])) { case 4: int[] exGrades1 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7])}; addGrade(studentID, studentName, courseName, exGrades1); break; case 5: int[] exGrades2 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8])}; addGrade(studentID, studentName, courseName, exGrades2); break; case 6: int[] exGrades3 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9])}; addGrade(studentID, studentName, courseName, exGrades3); break; case 7: int[] exGrades4 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10])}; addGrade(studentID, studentName, courseName, exGrades4); break; case 8: int[] exGrades5 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10]), Integer.parseInt(data[11])}; addGrade(studentID, studentName, courseName, exGrades5); break; case 9: int[] exGrades6 = {Integer.parseInt(data[4]), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7]), Integer.parseInt(data[8]), Integer.parseInt(data[9]), Integer.parseInt(data[10]), Integer.parseInt(data[11]), Integer.parseInt(data[12])}; addGrade(studentID, studentName, courseName, exGrades6); break; default: System.out.println("wrong format"); } } } } else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } }else { System.out.println("wrong format"); } } } // 输出结果 outputStudentGradeAverage(); outputCourseGradeAverage(); outputClassGradeAverage(); } /** * 添加课程信息 */ /** * 添加课程信息 */ private static void addCourse(String courseName, String courseType, String accessMode) { if (courses.containsKey(courseName)) { }else { boolean isExam = "考试".equals(accessMode); boolean isRequired = "必修".equals(courseType); if (isRequired && !isExam) { System.out.println(courseName + " : course type & access mode mismatch"); }else{ Course course = new Course(courseName, isRequired, isExam); courses.put(courseName, course); } } } /** * 添加成绩信息 */ private static void addGrade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade) { int flag1 = 0; for(int i = 0; i < courses.get(courseName).getGrades().size(); i++) { if (courses.get(courseName).getGrades().get(i).getStudentID().equals(studentID)){ flag1 = 1; break; } } if(flag1 == 0) { if ((!courses.get(courseName).isExam() && courses.get(courseName).isRequired())) { // 课程不存在,输出错误信息 System.out.println(courseName + " does not exist"); } Course course = courses.get(courseName); if ((dailyGrade == -1) == course.isExam()) { // 成绩数量和考核方式不匹配,输出错误信息 System.out.println(studentID + " " + studentName + " : access mode mismatch"); finalGrade = -1; } if (!course.isExam() && course.isRequired()) { finalGrade = -1; } if (finalGrade > 100 || dailyGrade > 100 ) { System.out.println("wrong format"); } else { Grade grade = new Grade(studentID, studentName, courseName, dailyGrade, finalGrade,null); grades.add(grade); courses.get(courseName).addGrade(grade); } } } private static void addGrade(String studentID, String studentName, String courseName, int[] exGrades) { int flag1 = 0; for(int i = 0; i < courses.get(courseName).getGrades().size(); i++) { if (courses.get(courseName).getGrades().get(i).getStudentID().equals(studentID)){ flag1 = 1; break; } } if(flag1 == 0) { if ((!courses.get(courseName).isExam() && courses.get(courseName).isRequired())) { // 课程不存在,输出错误信息 System.out.println(courseName + " does not exist"); } Course course = courses.get(courseName); for (int i:exGrades) { if (i < 0 || i > 100) { System.out.println("wrong format"); return; } } Grade grade = new Grade(studentID, studentName, courseName, -1, -2,exGrades); grades.add(grade); courses.get(courseName).addGrade(grade); } } /** * 输出学生所有课程总成绩的平均分 */ private static void outputStudentGradeAverage() { // 将grades按学号从小到大排序 Collections.sort(grades, Comparator.comparing(Grade::getStudentID)); // 使用TreeMap保存学生信息并排序 Map<String, Student> students = new TreeMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); if (!students.containsKey(studentID)) { students.put(studentID, new Student(studentID, grade.getStudentName())); } Student student = students.get(studentID); student.addGrade(grade); } // 遍历并输出每个学生的平均分 for (String studentID : students.keySet()) { Student student = students.get(studentID); double averageGrade = student.getAverageGrade(); if (averageGrade == -1) { System.out.println(studentID + " " + student.getStudentName() + " did not take any exams"); } else { System.out.println(studentID + " " + student.getStudentName() + " " + (int) averageGrade); } } } /** * 输出单门课程成绩平均分 */ private static void outputCourseGradeAverage() { // 按课程名称的字母顺序排序 List<String> courseNames = new ArrayList<>(courses.keySet()); // 使用 Collator 比较字符串的大小,实现按照汉字字母顺序排序 Collator collator = Collator.getInstance(Locale.CHINA); Collections.sort(courseNames, collator::compare); for (String courseName : courseNames) { Course course = courses.get(courseName); if(!grades.isEmpty()){ for(int i=0;i<grades.size();i++) course.addGrade(grades.get(i)); } if(!course.isExam() && course.isRequired()) { }else{ if (course.isExam()) { // 考试课程,需要计算平时成绩和总成绩平均分 double dailyAverage = course.getDailyAverage(); double finalAverage = course.getFinalAverage(); double totalAverage = course.getTotalAverage(); if(totalAverage == -1||totalAverage == 0) { System.out.println(courseName + " has no grades yet"); } else { System.out.println(courseName + " " + (int) dailyAverage + " " + (int) finalAverage + " " + (int) totalAverage); } } else { // 考察课程,只需要计算期末成绩平均分 double finalAverage = course.getFinalAverage(); double totalAverage = course.getTotalAverage(); if (finalAverage == -1) { System.out.println(courseName + " has no grades yet"); } else if (finalAverage == -2) { System.out.println(courseName + " " + (int) totalAverage); }else { System.out.println(courseName + " " + (int) finalAverage + " " + (int) finalAverage); } } } } } /** * 输出班级所有课程总成绩平均分 */ private static void outputClassGradeAverage() { Map<String, List<Grade>> classGrades = new HashMap<>(); for (Grade grade : grades) { String studentID = grade.getStudentID(); String classID = studentID.substring(0, 6); if (!classGrades.containsKey(classID)) { classGrades.put(classID, new ArrayList<>()); } classGrades.get(classID).add(grade); } List<String> classIDs = new ArrayList<>(classGrades.keySet()); // 按班级号从小到大排序 Collections.sort(classIDs); for (String classID : classIDs) { List<Grade> classGradeList = classGrades.get(classID); double totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : classGradeList) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeSum == -1) { System.out.println(classID + " has no grades yet"); } else { double totalAverageGrade = totalGradeSum / totalGradeCount; System.out.println(classID + " " + (int) totalAverageGrade); } } } } class Course { String courseName; // 课程名称 boolean isRequired; // 是否必修 boolean isExam; // 是否考试 List<Grade> grades = new ArrayList<>(); // 成绩列表 public Course(String courseName, boolean isRequired, boolean isExam) { this.courseName = courseName; this.isRequired = isRequired; this.isExam = isExam; } public boolean isExam() { return isExam; } public boolean isRequired() { return isRequired; } /** * 添加成绩到该课程 */ public void addGrade(Grade grade) { if (grade.getCourseName().equals(courseName)) { grades.add(grade); } } /** * 计算平时成绩平均分 */ public double getDailyAverage() { int dailyGradeSum = 0; int dailyGradeCount = 0; for (Grade grade : grades) { int dailyGrade = grade.getDailyGrade(); if (dailyGrade != -1) { dailyGradeSum += dailyGrade; dailyGradeCount++; } } if (dailyGradeCount == 0) { return 0; } return (double) dailyGradeSum / dailyGradeCount; } /** * 计算期末成绩平均分 */ public double getFinalAverage() { int finalGradeSum = 0; int finalGradeCount = 0; for (Grade grade : grades) { int finalGrade = grade.getFinalGrade(); finalGradeSum += finalGrade; finalGradeCount++; } if (finalGradeCount == 0) { return -1; } return (double) finalGradeSum / finalGradeCount; } /** * 计算总成绩平均分 */ public double getTotalAverage() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return 0; } return (double) totalGradeSum / totalGradeCount; } public List<Grade> getGrades(){ return grades; } } class Grade { private String studentID; // 学号 private String studentName; // 姓名 private String courseName; // 课程名称 private int dailyGrade; // 平时成绩,如果没有则为-1 private int finalGrade; // 期末成绩 private int[] exGrades; // 实验成绩 public Grade(String studentID, String studentName, String courseName, int dailyGrade, int finalGrade, int[] exGrades) { this.studentID = studentID; this.studentName = studentName; this.courseName = courseName; this.dailyGrade = dailyGrade; this.finalGrade = finalGrade; this.exGrades = exGrades; } public String getStudentID() { return studentID; } public String getStudentName() { return studentName; } public String getCourseName() { return courseName; } public int getDailyGrade() { return dailyGrade; } public int getFinalGrade() { return finalGrade; } /** * 计算总成绩 */ public double getTotalGrade() { if(dailyGrade == -1 && finalGrade == -2){ int sum = 0; int count = 0; for (int i:exGrades) { sum+=i; count++; } return (int)sum / count; } else if (dailyGrade == -1) { return finalGrade; } else if (finalGrade == -1){ return finalGrade; } else { return dailyGrade * 0.3 + finalGrade * 0.7; } } } class Student { private List<Grade> grades = new ArrayList<>(); // 成绩列表 private String studentID; // 学号 private String studentName; // 姓名 public Student(String studentID, String studentName) { this.studentID = studentID; this.studentName = studentName; } public String getStudentName() { return studentName; } public void addGrade(Grade grade) { if (grade.getStudentID().equals(studentID)) { grades.add(grade); } } /** * 计算该学生所有课程的总成绩平均分 */ public double getAverageGrade() { int totalGradeSum = 0; int totalGradeCount = 0; for (Grade grade : grades) { double totalGrade = grade.getTotalGrade(); if (!Double.isNaN(totalGrade)) { totalGradeSum += totalGrade; totalGradeCount++; } } if (totalGradeCount == 0) { return -1; } else { return (double) totalGradeSum / totalGradeCount; } } }
三、踩坑心得
1.对于学习过的东西要及时复习,不然容易忘记,这次的题目集主要用于复习之前所学知识,有些知识虽然之前学过,但是应为没有及时复习,也会变得陌生,所以要及时复习。
2.写代码前一定要先思考,构建好框架,设计好类图,否则后续的功能实现会变得十分复杂,并且及时你实现了当前所需的功能,也要考虑代码的复用性和可移植性。
四、改进建议
1.减少重复代码:重复的代码会增加维护成本和错误的可能性。可以通过提取公共代码块为函数或方法,或者使用循环来减少重复代码。
2.增加代码的可读性:可读性是一个好的代码的重要特征。可以通过使用有意义的变量名、添加注释、缩进和格式化代码等方式来提高代码的可读性。
五、总结
通过这次的阶段性总结,我深刻懂得了以下一些事情,首先,在解决问题时,需要理解问题需求:在开始编写代码之前,我首先花时间仔细阅读和理解问题的需求。这有助于我确定代码的目标和要求,并为我后续的编码工作提供指导。其次需要设计合适的类和方法:针对问题需求,我学会了如何设计合适的类和方法。这包括确定类的属性和行为,以及定义方法的输入和输出。良好的类设计可以提高代码的可读性和可维护性。总的来说,这次Java作业让我更深入地了解了面向对象编程的思想和Java语言的特性。我也学到了一些重要的编程技巧和最佳实践,这将对我的未来编码工作有所帮助。
六、评价
教学理念(OBE): 客观性评价:教学理念(OBE)是一种以学生为中心的教学方法,旨在培养学生的综合能力和实际应用能力。通过设置明确的学习目标和评估标准,OBE强调学生的学习成果和能力的发展。
建议及意见:OBE教学理念注重学生的主动参与和自主学习,这是非常有益的。然而,在实施过程中,需要确保学生能够真正理解和掌握知识,而不仅仅是追求表面的学习成果。建议教师在设计教学活动时,注意将知识与实际应用相结合,提供具体的案例和问题,激发学生的思考和创造力。
教学方法(边讲边练): 客观性评价:边讲边练是一种结合理论讲解和实践练习的教学方法。通过让学生在课堂上积极参与练习和解决问题,提高他们的学习效果和能力。
建议及意见:边讲边练的教学方法能够增加学生的参与度和学习动力,但需要注意平衡讲解和练习的比例。建议教师在讲解知识点时,结合实例和案例进行说明,然后引导学生进行练习和实践,巩固所学知识。此外,教师还可以使用互动式教学工具和技术,如小组讨论、互动游戏等,激发学生的学习兴趣和积极性。
教学组织(线上线下混合式教学): 客观性评价:线上线下混合式教学是一种结合传统教学和在线教学的教学组织方式。它可以提供灵活的学习环境,促进学生的自主学习和合作学习。
建议及意见:线上线下混合式教学能够充分利用在线教育资源和工具,提供更多的学习机会和学习方式。建议教师在教学组织上,合理安排线上和线下的学习活动,确保学生能够充分利用线上资源进行预习和复习,并在线下课堂上进行实践和互动。此外,教师还应提供明确的学习指导和支持,帮助学生克服线上学习的困难和挑战。
教学过程(PTA题目集驱动): 客观性评价:PTA题目集驱动是一种以题目集为基础的教学过程。通过选择和设计与学习目标相匹配的题目集,教师可以引导学生进行有针对性的学习和练习。
建议及意见:PTA题目集驱动的教学过程能够帮助学生更好地理解和掌握知识,提高他们的解决问题的能力。建议教师在选择题目集时,要根据学生的实际情况和学习进度进行调整,确保题目的难度和复杂度适合学生的能力水平。此外,教师还应提供充足的练习机会和反馈,帮助学生发现和纠正错误,进一步提高学习效果。
教学模式(BOPPPS): 客观性评价:BOPPPS教学模式是一种结构化的教学模式,包括预习、目标、前导、主体、实践、评估、总结等步骤。它能够帮助教师组织教学活动和引导学生的学习过程。
建议及意见:BOPPPS教学模式能够提供清晰的学习目标和教学步骤,有助于学生的学习和理解。建议教师在使用BOPPPS模式时,要根据学生的实际情况和学习需求进行调整,确保每个步骤都能够达到预期的效果。此外,教师还应提供充足的实践和练习机会,帮助学生巩固所学知识和技能。
总体建议:在教学过程中,教师应注重培养学生的实际应用能力和综合能力,而不仅仅追求学习成绩和表面的知识掌握。建议教师结合具体的课程内容和学生的实际情况,设计多样化的教学活动和评估方式,激发学生的学习兴趣和积极性。此外,教师还应提供充足的学习资源和支持,帮助学生克服学习难题和困难,实现个人的学习目标。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!