import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { private static final int COURSE_RECORD_TYPE = 1; private static final int SCORE_RECORD_TYPE = 2; private final ParseInput parseInput; public Main() { parseInput = new ParseInput(); } public static void main(String[] args) { Main main = new Main(); main.run(); } private void run() { Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); while (!input.equals("end")) { parseInput.parseInput(input); input = scanner.nextLine(); } parseInput.showStudents(); parseInput.showCourses(); parseInput.showClasses(); }} class Cls implements Comparable<Cls> { private final String id; private final ArrayList<Student> students; public Cls(String id) { this.id = id; students = new ArrayList<>(); } public String getId() { return id; } public void addStudent(Student student) { students.add(student); } public ArrayList<Student> getStudents() { return students; } @Override public int compareTo(Cls o) { return id.compareTo(o.getId()); }} class Student implements Comparable<Student> { private final String id; private final String name; private Cls cls; public Student(String name, String id) { this.name = name; this.id = id; } public String getName() { return name; } public void setCls(Cls cls) { this.cls = cls; } public Cls getCls() { return cls; } public String getId() { return id; } @Override public int compareTo(Student o) { return id.compareTo(o.getId()); }} class ParseInput { private static final int COURSE_RECORD_TYPE = 0; private static final int SCORE_RECORD_TYPE =0 ; private final ArrayList<Course> courses; private final ArrayList<Student> students; private final ArrayList<ChooseCourse> chooseCourses; private final ArrayList<Cls> classes; public ParseInput() { courses = new ArrayList<>(); students = new ArrayList<>(); chooseCourses = new ArrayList<>(); classes = new ArrayList<>(); } public void parseInput(String input) { String[] items = input.split(" "); int type = InputMatching.matchingInput(input); if (type == 1/*COURSE_RECORD_TYPE*/) { parseCourseRecord(items); } else if (type == /*SCORE_RECORD_TYPE*/2) { parseScoreRecord(items); } else { System.out.println("wrong format"); } } private void parseCourseRecord(String[] items) { String courseName = items[0]; String courseType = items[1]; String checkType = items[2]; Course course = new Course(courseName, courseType, checkType); if (!checkCourse(course)) { return; } if (getCourse(courseName) == null) { course = new Course(courseName, courseType, checkType); courses.add(course); } } private boolean checkCourse(Course course) { int courseType, accessType; if (course.getType().equals("必修")) { courseType = 0; } else if (course.getType().equals("选修")) { courseType = 1; } else { courseType = -1; } if (course.getMethod().equals("考试")) { accessType = 0; } else if (course.getMethod().equals("考察")) { accessType = 1; } else { accessType = -1; } if (courseType == 0 && (accessType == 0)) { return true; } if (courseType == 1 && (accessType == 0 || accessType == 1)) { return true; } System.out.println(course.getName() + " : course type & access mode mismatch"); return false; } private void parseScoreRecord(String[] items) { String stuId = items[0]; String stuName = items[1]; String courseName = items[2]; String clsId = stuId.substring(0, 6); Cls cls; Student stu; cls = getCls(clsId); if (cls == null) { cls = new Cls(clsId); classes.add(cls); } stu = getStudent(stuId); if (stu == null) { stu = new Student(stuName, stuId); students.add(stu); cls.addStudent(stu); } stu.setCls(cls); Course course = getCourse(courseName); if (course == null) { System.out.println(courseName + " does not exist"); return; } if (!checkGrade(items, course)) { return; } Grade grade; if (items.length == 4) { int finalScore = Integer.parseInt(items[3]); grade = new AssessmentGrade(finalScore); } else { int usualScore = Integer.parseInt(items[3]); int finalScore = Integer.parseInt(items[4]); grade = new ExaminationGrade(usualScore, finalScore); } if (existChooseCourse(stu, course)) { return; } ChooseCourse chooseCourse = new ChooseCourse(course, stu, grade); chooseCourses.add(chooseCourse); } private boolean existChooseCourse(Student stu, Course course) { for (ChooseCourse chooseCourse : chooseCourses) { if (chooseCourse.getCourse().getName().equals(course.getName())) { if (chooseCourse.getStudent().getName().equals(stu.getName())) { return true; } } } return false; } private boolean checkGrade(String[] items, Course course) { String courseType = course.getMethod(); if (courseType.equals("考试") && items.length == 5) { return true; } if (courseType.equals("考察") && items.length == 4) { return true; } System.out.println(items[0] + " " + items[1] + " : access mode mismatch"); return false; } public void showStudents() { Collections.sort(students); for (Student student : students) { ArrayList<ChooseCourse> studentCourseSelects = getStudentSelects(student.getId()); if (studentCourseSelects.size() != 0) { System.out.println(student.getId() + " " + student.getName() + " " + getAvgTotalScore(studentCourseSelects)); } else { System.out.println(student.getId() + " " + student.getName() + " did not take any exams"); } } } public void showCourses() { for (Course course : courses) { ArrayList<ChooseCourse> courseSelects = getCourseSelects(course.getName()); if (courseSelects.size() == 0) { System.out.println(course.getName() + " has no grades yet"); } else { if (course.getMethod().equals("考试")) { System.out.println(course.getName() + " " + getAvgUsualScore(courseSelects) + " " + getAvgFinalScore(courseSelects) + " " + getAvgTotalScore(courseSelects)); } else { System.out.println(course.getName() + " " + getAvgFinalScore(courseSelects) + " " + getAvgTotalScore(courseSelects)); } } } } public void showClasses() { Collections.sort(classes); for (Cls cls : classes) { ArrayList<ChooseCourse> classCourseSelects = getClassSelects(cls.getId()); if (classCourseSelects.size() == 0) { System.out.println(cls.getId() + " has no grades yet"); } else { System.out.println(cls.getId() + " " + getAvgTotalScore(classCourseSelects)); } } } private static int getAvgUsualScore(ArrayList<ChooseCourse> courseSelects) { int sum = 0; for (ChooseCourse cs : courseSelects) { sum += ((ExaminationGrade) cs.getGrade()).getUsualScore(); } return sum / courseSelects.size(); } public int getAvgTotalScore(ArrayList<ChooseCourse> listChooseCourse) { int sum = 0; for (ChooseCourse cs : listChooseCourse) { sum += cs.getGrade().getTotalScore(); } return sum / listChooseCourse.size(); } private static int getAvgFinalScore(ArrayList<ChooseCourse> courseSelects) { int sum = 0; for (ChooseCourse cs : courseSelects) { sum += cs.getGrade().getFinalScore(); } return sum / courseSelects.size(); } private ArrayList<ChooseCourse> getClassSelects(String className) { getCls(className); ArrayList<ChooseCourse> classSelects = new ArrayList<>(); for (ChooseCourse cs : chooseCourses) { if (className.equals(cs.getStudent().getCls().getId())) { classSelects.add(cs); } } return classSelects; } private ArrayList<ChooseCourse> getStudentSelects(String stuId) { ArrayList<ChooseCourse> stuSelects = new ArrayList<>(); for (ChooseCourse cs : chooseCourses) { if (stuId.equals(cs.getStudent().getId())) { stuSelects.add(cs); } } return stuSelects; } private ArrayList<ChooseCourse> getCourseSelects(String courseName) { ArrayList<ChooseCourse> courseSelects = new ArrayList<>(); for (ChooseCourse cs : chooseCourses) { if (courseName.equals(cs.getCourse().getName())) { courseSelects.add(cs); } } return courseSelects; } private Cls getCls(String clsId) { for (Cls cls : classes) { if (cls.getId().equals(clsId)) { return cls; } } return null; } private Student getStudent(String stuId) { for (Student student : students) { if (student.getId().equals(stuId)) { return student; } } return null; } private Course getCourse(String courseName) { for (Course course : courses) { if (course.getName().equals(courseName)) { return course; } } return null; }} class ChooseCourse { private final Course course; private final Student student; private final Grade grade; public ChooseCourse(Course course, Student student, Grade grade) { this.course = course; this.grade = grade; this.student = student; } public Student getStudent() { return student; } public Course getCourse() { return course; } public Grade getGrade() { return grade; }} class InputMatching { private static final String STU_NUM_MATCHING = "\\d{8}"; private static final String STU_NAME_MATCHING = "[^ \t]{1,10}"; private static final String SCORE_MATCHING = "([1-9]?[0-9]|100)"; private static final String COURSE_NAME_MATCHING = "[^ \t]{1,10}"; private static final String COURSE_TYPE_MATCHING = "(选修|必修)"; private static final String CHECK_COURSE_TYPE_MATCHING = "(考试|考察)"; private static final String SCORE_MATCHING1 = "(\\s([1-9]?[0-9]|100))?"; private static final String COURSE_INPUT_PATTERN = COURSE_NAME_MATCHING + " " + COURSE_TYPE_MATCHING + " " + CHECK_COURSE_TYPE_MATCHING; private static final String SCORE_INPUT_PATTERN = STU_NUM_MATCHING + " " + STU_NAME_MATCHING + " " + COURSE_NAME_MATCHING + " " + SCORE_MATCHING + SCORE_MATCHING1; public static int matchingInput(String input) { if (matchingCourse(input)) { return 1; } if (matchingScore(input)) { return 2; } return 0; } private static boolean matchingCourse(String input) { return input.matches(COURSE_INPUT_PATTERN); } private static boolean matchingScore(String input) { return input.matches(SCORE_INPUT_PATTERN); }} class Course implements Comparable<Course> { private final String name; private final String type; private final String method; public Course(String name, String type, String method) { this.name = name; this.type = type; this.method = method; } public String getName() { return name; } public String getType() { return type; } public String getMethod() { return method; } @Override public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(name, o.getName()); }} abstract class Grade { protected final int finalScore; protected final int totalScore; public Grade(int finalScore) { this.finalScore = finalScore; this.totalScore = finalScore; } public int getTotalScore() { return totalScore; } public int getFinalScore() { return finalScore; }} class ExaminationGrade extends Grade { private final int usualScore; public ExaminationGrade(int usualScore, int finalScore) { super(finalScore); this.usualScore = usualScore; } public int getUsualScore() { return usualScore; } @Override public int getTotalScore() { return (int) (finalScore * 0.7 + usualScore * 0.3); }} class AssessmentGrade extends Grade { public AssessmentGrade(int finalScore) { super(finalScore); }}
这段代码是一个学生成绩管理系统的实现。它包含了一些类和方法来处理输入数据并计算学生成绩的平均值。
首先呢先来讲讲各个类的作用
-
Main(主要类):这个类是程序的入口点,包含了主要的方法,负责运行程序并处理用户输入。
-
Cls(班级类):表示一个班级,以其ID来标识,并包含一个属于该班级的学生列表。
-
Student(学生类):表示一个学生,以姓名和ID来标识。它还拥有一个指向所属班级的引用。
-
ParseInput(解析输入类):负责解析用户输入并根据输入执行相应的操作。它维护了课程、学生、选课(学生、课程和成绩的组合)和班级的列表。它还提供了分析和显示基于输入数据的各种统计信息的方法。
-
ChooseCourse(选课类):表示学生选择的课程,并存储相关的课程、学生和成绩信息。
-
InputMatching(输入匹配类):这个工具类包含了将用户输入进行匹配和分类到不同类型(课程或成绩记录)的方法。
-
Course(课程类):表示一门课程,以课程名来标识。它还存储了课程的类型(必修课或选修课)和评估方式(考试或评估)。
-
Grade(成绩类):这是一个抽象类,是其他不同类型成绩的基类。它存储了课程的最终成绩和总分。
-
ExaminationGrade(考试成绩类):表示基于考试评估的成绩,包括平时成绩和计算最终成绩的总分(最终成绩和平时成绩的加权平均)。
-
AssessmentGrade(评估成绩类):表示基于评估的成绩,只包含最终成绩。
这道题目看起来十分难,但是只要静下心来把结构分析清楚,其实并不是一个非常难的题目,只是类比较多也比较麻烦。
这一道题目最主要的踩坑点就是,非常建议使用Arrylist类来写代码,不然十分容易导致运行超时,还有一些地方需要添加return0,不然的话就会造成非零返回,具体原理是啥其实我自己也没有搞清楚,但是需要注意的是就是一定要静下心来,不然的话这道题目的代码量很大,很容易就会写烦躁,就会越写越烦然后导致根本写不出来。
至于有哪些地方可以改进,我认为是注释太少了,因为我本人其实是没有写注释的习惯的,但是大家要养成写注释的习惯,这一点我在以后也会改进。
import java.util.HashMap; import java.util.Scanner; class Main{ public static void main(String[] args) { HashMap<String, Student> map = new HashMap<>(); Scanner sc = new Scanner(System.in); while (true) { String input = sc.nextLine(); if (input.equals("end")) { break; } // 根据输入直接创建 Student 对象,并将其添加至 HashMap 中 String[] info = input.split(" "); Student student = new Student(info[0], info[1], Integer.parseInt(info[2])); map.put(student.getId(), student); } // 根据学号直接从 HashMap 中获取对应的学生信息,并输出查询结果 String id = sc.nextLine(); Student student = map.get(id); if (student != null) { System.out.println(student.getId() + " " + student.getName() + " " + student.getScore()); } else { System.out.println("The student " + id + " does not exist"); } } } // 定义学生类,包括学号、姓名和成绩属性 class Student { private String id; private String name; private int score; public Student(String id, String name, int score) { this.id = id; this.name = name; this.score = score; } public String getId() { return id; } public String getName() { return name; } public int getScore() { return score; } }
首先先分析一下新的知识点:
HashMap类:这个类用于存储键值对,并支持基于键快速查找对应的值。在这个代码中,HashMap被用于存储学生对象,使用学号作为键。字符串处理:代码中使用了split方法将输入的字符串按空格分割成数组,以提取学生信息。
那么首先我们先来分析一下这段代码的逻辑:
- 导入必要的类:HashMap和Scanner。
- 创建了一个HashMap对象和一个Scanner对象。
- 进入一个无限循环,循环内部读取控制台的输入。
- 将输入按空格分割成字符串数组。
- 使用字符串数组中的元素创建一个Student对象,并将其添加到HashMap中,使用学号作为键。
- 循环结束后,读取控制台的输入并将其存储在变量id中。
- 使用id在HashMap中查找对应的Student对象。
- 如果找到了学生对象,则输出学生的学号、姓名和成绩。
- 如果未找到学生对象,则输出错误消息。
踩坑心得:这段代码如果实在写不出来的话可以不用死磕HashMap类来写,可以试试更为简单的。
改进建议:老问题,还是注释,还有便是封装实现的不是很好,目前的代码采用简单的方式处理学生信息,只有学号、姓名和成绩。可以考虑创建更复杂的学生类,包含更多的属性和方法,例如课程列表、班级信息等。目前的代码主要集中在Main类中,包含了输入处理、学生对象的创建和查询等功能。可以考虑将不同的功能部分封装到独立的方法或类中,以提高代码的可重用性和可维护性。
import java.util.Map; import java.util.Scanner; import java.util.TreeMap; public class Main { public static void main(String[] args) { Map<String, Student> map = new TreeMap<>((o1, o2) -> Integer.parseInt(o2) - Integer.parseInt(o1)); Scanner sc = new Scanner(System.in); while (true) { String input = sc.nextLine(); if (input.equals("end")) { break; } String[] info = input.split(" "); String id = info[0]; String name = info[1]; int score = Integer.parseInt(info[2]); Student student = new Student(name, score); map.put(id, student); } for (Map.Entry<String, Student> entry : map.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue().getName() + " " + entry.getValue().getScore()); } } } class Student { private String name; private int score; public Student(String name, int score) { this.name = name; this.score = score; } public String getName() { return name; } public int getScore() { return score; } }
同上,首先先来梳理一下他的结构:
- 导入必要的类:Map、Scanner和TreeMap。
- 创建了一个TreeMap对象和一个Scanner对象。
- 进入一个无限循环,循环内部读取控制台的输入。
- 如果输入为"end",则跳出循环。
- 将输入按空格分割成字符串数组,并提取出学号、姓名和成绩。
- 使用姓名和成绩创建一个Student对象。
- 将学号作为键,学生对象作为值,将键值对添加到TreeMap中。
- 循环结束后,遍历TreeMap,按学号逆序输出学生的学号、姓名和成绩。
- TreeMap会根据学号的自然顺序(递减)对键进行排序,从而实现逆序输出。
这段代码是根据上一题改进的,改进后的代码主要在保存学生对象的数据结构上使用了TreeMap,这使得按学号逆序输出学生信息变得更加简单。同样,学生对象的创建和学生信息的输出也保持了之前代码的逻辑。通过这些改进,代码的可读性和排序功能得到了提升。
踩坑心得:这段代码如果实在写不出来的话可以不用死磕HashMap类来写,可以试试更为简单的。
import java.util.*; import java.text.Collator; import java.util.ArrayList; import java.util.Locale; import java.util.Objects; import java.util.ArrayList; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); HashSet<CourseSelection> courseSelectionHashSet = new HashSet<>(); HashSet<String> courseNameSet = new HashSet<>(); HashMap<Student, Boolean> studentScorehashMap = new HashMap<>(); TreeMap<Student, Integer> averageStudentScore = new TreeMap<>(); TreeMap<Course, Integer> courseUsualAverage = new TreeMap<>(); TreeMap<Course, Integer> courseFinalAverage = new TreeMap<>(); TreeMap<Course, Integer> courseCombinedAverage = new TreeMap<>(); TreeMap<String, Integer> classCombinedAverage = new TreeMap<>(); StringBuilder stringBuilder = new StringBuilder(); while (true) { String temp = scanner.nextLine(); if (temp.equals("end")) { break; } String[] s = temp.split(" "); if (s[0].matches("[0-9]{0,100}")) { Student student = new Student(s[0], s[1]); Course course = null; if(s.length>=5) { int flag = 0; for (int i = 4; i < s.length; i++) { if (!s[i].matches("[0-9]{1,3}")) { System.out.println("wrong format"); flag = 1; break; } else if (Integer.parseInt(s[i]) < 0 || Integer.parseInt(s[i]) > 100) { System.out.println("wrong format"); flag = 1; break; } } if (flag == 1) continue; } if (s[0].length() != 8 || s[1].length() > 10 || s[2].length() > 10 || !s[3].matches("[0-9]{1,3}") || (Integer.parseInt(s[3]) < 0 || Integer.parseInt(s[3]) > 100)) { System.out.println("wrong format"); continue; } if (courseNameSet.contains(s[2])) { for (Course tempCourse : courseUsualAverage.keySet()) { if (tempCourse.name.equals(s[2])) { course = tempCourse; break; } } } if (s.length == 5 && ((Integer.parseInt(s[4]) < 0) || (Integer.parseInt(s[4]) > 100))) { System.out.println("wrong format"); continue; } else if(course!=null&&course.mode==2){ if (!s[3].matches("[4-9]")) { System.out.println("wrong format"); continue; } if (s.length != Integer.parseInt(s[3]) + 4) { System.out.println(s[0] + " " + s[1] + " " + ": access mode mismatch"); classCombinedAverage.put(s[0].substring(0, 6), 0); averageStudentScore.put(student, 0); continue; } } if(!courseNameSet.contains(s[2])) { System.out.println(s[2] + " does not exist"); averageStudentScore.put(student, 0); classCombinedAverage.put(s[0].substring(0, 6), 0); continue; } Grade grade = new ExamScore(); if (s.length == 4 && course.mode == 1) { grade = new ExamineGrade(); grade.finalGrade = Integer.parseInt(s[3]); } else if (s.length == 5 && course.mode == 0) { grade = new ExamScore(); grade.usualGrade = Integer.parseInt(s[3]); grade.finalGrade = Integer.parseInt(s[4]); } else if (course.mode == 2) { grade = new ExperimentalScore(); for (int i = 4; i < s.length; i++) { grade.experimentalGrades.add(Integer.parseInt(s[i])); } } classCombinedAverage.put(s[0].substring(0, 6), 0); if ((s.length == 4 && course.mode == 0) || (s.length == 5 && course.mode == 1)) { System.out.println(s[0] + " " + s[1] + " " + ": access mode mismatch"); averageStudentScore.put(student, 0); continue; } //获取每个同学,以便计算平均分 averageStudentScore.put(student, 0); CourseSelection courseSelection = new CourseSelection(course, student, grade); courseSelectionHashSet.add(courseSelection); } else { if (s.length != 3 && s.length != 2) { System.out.println("wrong format"); continue; } if ((s.length == 3) && (s[0].length() > 10 || ((!s[1].equals("必修") && !s[1].equals("选修") && !s[1].equals("实验")) || (!s[2].equals("考试") && !s[2].equals("考察") && !s[2].equals("实验"))))) { System.out.println("wrong format"); continue; } else if ((s.length == 2) && (s[0].length() > 10 || !s[1].equals("必修"))) { System.out.println("wrong format"); continue; } int type = 0; if (s[1].equals("必修")) type = 0; if (s[1].equals("选修")) type = 1; if (s[1].equals("实验")) type = 2; Course course = new Course(s[0], type); if (s.length == 3) { int mode = 0; if (s[2].equals("考试")) mode = 0; if (s[2].equals("考察")) mode = 1; if (s[2].equals("实验")) mode = 2; course.mode = mode; } if ((course.type == 0 && course.mode == 1) || (course.mode == 2 && course.type != 2) || course.type == 2 && course.mode != 2) { System.out.println(s[0] + " : course type & access mode mismatch"); continue; } courseUsualAverage.put(course, 0); courseFinalAverage.put(course, 0); courseCombinedAverage.put(course, 0); courseNameSet.add(s[0]); } } //courseSelectionHashSet.stream().map(s->s.course.name).forEach(System.out::println); //1.求每个同学平均成绩,排序打印 for (Student student : averageStudentScore.keySet()) { List<Integer> list = new ArrayList<>(); for (CourseSelection courseSelection : courseSelectionHashSet) { if (courseSelection.student.id.equals(student.id)) { list.add(courseSelection.grade.getGrade()); } } //List<Integer> list = courseSelectionHashSet.stream().filter(s -> s.student.id.equals(student.id)).map(s -> s.grade.getGrade()).toList(); for (Integer tempScore : list) { averageStudentScore.replace(student, averageStudentScore.get(student) + tempScore); } if (list.size() != 0) averageStudentScore.replace(student, averageStudentScore.get(student) / list.size()); if (list.size() == 0) { studentScorehashMap.put(student, false); System.out.println(student.id + " " + student.name + " " + "did not take any exams"); } else { studentScorehashMap.put(student, true); System.out.println(student.id + " " + student.name + " " + averageStudentScore.get(student)); } } //2.计算每门课程的平均 平时分,期末分,综合分 for (Course course : courseUsualAverage.keySet()) { List<Integer> list = new ArrayList<>(); List<Integer> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); //平时分 for (CourseSelection courseSelection : courseSelectionHashSet) { if (courseSelection.course.name.equals(course.name)) { list.add(courseSelection.grade.usualGrade); } } //list = courseSelectionHashSet.stream().filter(s -> s.course.name.equals(course.name)).map(s -> s.grade.usualGrade).toList(); //期末分 for (CourseSelection courseSelection : courseSelectionHashSet) { if (courseSelection.course.name.equals(course.name)) { list1.add(courseSelection.grade.finalGrade); } } //list1 = courseSelectionHashSet.stream().filter(s -> s.course.name.equals(course.name)).map(s -> s.grade.finalGrade).toList(); //综合分 for (CourseSelection courseSelection : courseSelectionHashSet) { if (courseSelection.course.name.equals(course.name)) { list2.add(courseSelection.grade.getGrade()); } } //list2 = courseSelectionHashSet.stream().filter(s -> s.course.name.equals(course.name)).map(s -> s.grade.getGrade()).toList(); for (Integer tempScore : list) { courseUsualAverage.replace(course, courseUsualAverage.get(course) + tempScore); } for (Integer tempScore : list1) { courseFinalAverage.replace(course, courseFinalAverage.get(course) + tempScore); } for (Integer tempScore : list2) { courseCombinedAverage.replace(course, courseCombinedAverage.get(course) + tempScore); } if (list.size() != 0) courseUsualAverage.replace(course, courseUsualAverage.get(course) / list.size()); if (list1.size() != 0) courseFinalAverage.replace(course, courseFinalAverage.get(course) / list1.size()); if (list2.size() != 0) courseCombinedAverage.replace(course, courseCombinedAverage.get(course) / list2.size()); if (list.size() == 0) { System.out.println(course.name + " has no grades yet"); } else { if (course.mode == 0) System.out.println(course.name + " " + courseUsualAverage.get(course) + " " + courseFinalAverage.get(course) + " " + courseCombinedAverage.get(course)); else if(course.mode!=2) System.out.println(course.name + " " + courseFinalAverage.get(course) + " " + courseCombinedAverage.get(course)); else System.out.println(course.name +" "+ courseCombinedAverage.get(course)); } } //3.计算班级的分数 for (String classId : classCombinedAverage.keySet()) { int sum = 0;//人数 boolean flag = false;//班级是否有分数记录 for (Student student : averageStudentScore.keySet()) { if (student.id.substring(0, 6).equals(classId)) { classCombinedAverage.replace(classId, classCombinedAverage.get(classId) + averageStudentScore.get(student)); if (studentScorehashMap.get(student)) { flag = true; sum++; } } } if (sum != 0) classCombinedAverage.replace(classId, classCombinedAverage.get(classId) / sum); if (flag) { System.out.println(classId + " " + classCombinedAverage.get(classId)); } else { System.out.println(classId + " " + "has no grades yet"); } } } } class Course implements Comparable<Course>{ protected String name; protected int type;//0为必修,1为选修,2为实验 protected int mode=0;//0为考试,1为考察,2为实验 public Course(String name, int type, int mode) { this.name = name; this.type = type; this.mode = mode; } public Course(String name){ this.name=name ; }; public Course(String name,int type){ this.name=name; this.type=type; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Course course = (Course) o; return Objects.equals(name, course.name); } @Override public int hashCode() { return Objects.hash(name); } @Override public int compareTo(Course o) { return Collator.getInstance(Locale.CHINA).compare(this.name, o.name); } } class CourseSelection { protected Course course; protected Student student; protected Grade grade; public CourseSelection(Course course, Student student, Grade grade) { this.course = course; this.student = student; this.grade = grade; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CourseSelection that = (CourseSelection) o; return Objects.equals(course, that.course) && Objects.equals(student, that.student); } @Override public int hashCode() { return Objects.hash(course, student); } } class ExamineGrade extends Grade{ @Override Integer getGrade() { return this.finalGrade; } public ExamineGrade(){ type=1; } } class ExamScore extends Grade{ @Override Integer getGrade() { return (int)( this.usualGrade*0.3+this.finalGrade*0.7); } public ExamScore(){ type=0; } } class ExperimentalScore extends Grade{ Integer getGrade(){ Integer result=0; for(Integer integer:experimentalGrades){ result+=integer; } return result/experimentalGrades.size(); } } abstract class Grade { protected Integer finalGrade=0; protected int type; protected Integer usualGrade=0; protected ArrayList<Integer>experimentalGrades=new ArrayList<>(); abstract Integer getGrade(); } class Student implements Comparable<Student>{ protected String id; protected String name; public Student() { } public Student(String id, String name) { this.id = id; this.name = name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return Objects.equals(id, student.id); } @Override public int hashCode() { return Objects.hash(id); } @Override public int compareTo(Student s) { return this.id.compareTo(s.id); } }
分析代码的逻辑:
该程序初始化了几个数据结构,如HashSet、HashMap和TreeMap,用于存储有关课程选择、学生成绩和课程平均分的信息。它使用Course、Student、CourseSelection和Grade等类来表示实体及其关系。
各个类的作用:
-
Course(课程)类:表示一个课程,它有课程名称等属性,并提供访问和设置这些属性的方法。
-
Student(学生)类:表示一个学生,它有学生的姓名、学号等属性,并提供访问和设置这些属性的方法。
-
CourseSelection(课程选择)类:表示学生选择的课程,它关联了学生和课程,并提供了相关方法来添加、移除和获取学生的课程选择。
-
Grade(成绩)类:表示学生在某门课程上的成绩,它关联了学生、课程和成绩,并提供了相关方法来设置和获取学生成绩。
-
CourseManagement(课程管理)类:这个类是程序的主要逻辑部分,它包含了主要的方法和循环,用于处理用户的输入和执行相应的操作。它使用上述类来管理学生、课程和成绩,并进行平均分的计算和显示。
踩坑心得:踩坑的同第一次的基本雷同
改进建议:使用更具表达力的类和方法命名:通过使用更具描述性的类和方法名称,可以提高代码的可读性。这样其他人在查看代码时能够更好地理解其功能,降低出错的可能性。优化数据结构的选择:根据实际需求和使用情况,可以优化选择数据结构。例如,在存储学生和课程的信息时,可以考虑使用ArrayList或LinkedHashMap等数据结构。添加更多的注释:为代码中的关键部分添加注释,可以增加代码的可维护性。注释应清晰地解释代码的意图和功能,这有助于团队成员理解和修改代码。
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; import java.text.Collator; import java.util.Comparator; public class Main { public static void main(String[] args) { Scanner in = new Scanner (System.in); //初始化一个Work类,开始读入数据 Work work = new Work(); //读入数据 String message = in.nextLine(); while (!message.equals("end")){ //当message不是end的时候 work.manage(message); //在Work类里面处理类 message = in.nextLine(); //读入下一行 } //输出学生 work.show_Student(); //输出课程 work.show_Course(); //输出班级 work.show_Classroom(); } } class Work { ArrayList<Student> listStudent = new ArrayList<>(); //学生表 ArrayList<Classroom> listClassroom = new ArrayList<>(); //班级表 ArrayList<Course> listCourse = new ArrayList<>(); //课程表 ArrayList<Message_Box> listMessage_Box = new ArrayList<>(); //选课记录表 InputMatching matching = new InputMatching(); public void manage(String message) { String Line[] = message.split(" " ); switch (matching.matchingInput(message)) { case 1 : { //输入的是课程 Course course = new Course(Line[0],Line[1],Line[2]); if (Error_Course((course))) { //性质没有问题 if (Exist_Course(course)) {//是否存在,应该放在最后??? if (Weight_error(Line)) { //是否权重数量对不上 if (Weight_sum_error(Line)) {//是否权重数量和==1 if (Line[2].equals("实验")) { for (int i = 4; i < Line.length; i++) { course.addWeight(Double.parseDouble(Line[i])); } } else if (Line[2].equals("考试")) { course.addWeight(Double.parseDouble(Line[3])); course.addWeight(Double.parseDouble(Line[4])); } else { course.addWeight(1); } listCourse.add(course); } else { System.out.println(Line[0] + " : weight value error"); } } else { System.out.println(Line[0] + " : number of scores does not match"); } } } else { System.out.println(course.getName() + " : course type & access mode mismatch"); } break; } case 2: { //输入的是学生 Course course = find_CourseByName(Line[2]); Student student = new Student(Integer.parseInt(Line[0]),Line[1]); Classroom classroom = new Classroom(student.getId()/100); if (Exist_Student(student)) listStudent.add(student); if (Exist_Classroom(classroom)) listClassroom.add(classroom); if (course!= null) { if (Line.length == 4) { if (course.getGrade_Way().equals("考察")){ Grade_Course grade_course = new Grade_Course(course,Line); // Grade grade = new Grade_Exam(Line[3]); //成绩加入得要改 Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else { System.out.println(Line[0] + " " + Line[1] + " : " +"access mode mismatch"); } } else { if (course.getGrade_Way().equals("考试") && Line.length == 5) { Grade_Course grade_course = new Grade_Course(course,Line); // Grade grade = new Grade_daily(Line[3],Line[4]); //成绩加入得要改 Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else if (course.getGrade_Way().equals("实验") && Line.length-3 == course.get_Weight_size()) { Grade_Course grade_course = new Grade_Course(course,Line); // Grade grade = new Grade_Lab(Line); //成绩加入得要改 Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else { System.out.println(Line[0] + " " + Line[1] + " : " +"access mode mismatch"); } } } else { System.out.println(Line[2] + " " + "does not exist"); } break; } default: { System.out.println("wrong format"); } } } private boolean Exist_Message(Message_Box messageBox) { for(Message_Box messageBox1 : listMessage_Box){ if ((messageBox.student.getId() == messageBox1.student.getId()) && (messageBox1.course.getName().equals(messageBox.course.getName()))){ return false; } } return true; } private boolean Exist_Classroom(Classroom classroom) { for(Classroom classroom1 : listClassroom){ if (classroom1.getClass_ID()==classroom.getClass_ID()){ return false; } } return true; } private boolean Exist_Student(Student student) { for (Student student1 : listStudent){ if (student1.getId() == student.getId()){ return false; } } return true; } private boolean Exist_Course(Course course) { for (Course course1 : listCourse){ if (course1.getName().equals(course.getName())){ return false; } } return true; } private boolean Weight_error(String[] Line) { if (Line[2].equals("实验")) { int number = Integer.parseInt(Line[3]); if (Line.length - 4 == number) return true; else return false; } else if (Line[2].equals("考试")){ if (Line.length - 3 == 2) return true; else return false; } else { return true; } } private boolean Weight_sum_error(String[] Line){ if (Line[2].equals("实验")) { double total = 0; int number = Integer.parseInt(Line[3]); for (int i = 4 ; i < number + 4 ; i++) { total += Double.parseDouble(Line[i]); } if (total==1) return true; else return false; } else if (Line[2].equals("考试")) { double total = Double.parseDouble(Line[3]) + Double.parseDouble(Line[4]); if (total==1) return true; else return false; } else { return true; } } private Course find_CourseByName(String name) { for (int i = 0 ; i < listCourse.size() ; i++) { if (listCourse.get(i).getName().equals((name))){ return listCourse.get(i); } } return null; } private boolean Error_Course(Course course) { if (course.getCourse_Message().equals("必修") && course.getGrade_Way().equals("考察")){ return false; } else if ((course.getCourse_Message().equals("实验") && !course.getGrade_Way().equals("实验")) || (!course.getCourse_Message().equals("实验") && course.getGrade_Way().equals("实验"))){ return false; } else { return true; } } public void show_Student() { //按学号排序 Collections.sort(listStudent); for (int i = 0 ; i < listStudent.size() ; i++) { //这里的循环是用来遍历每一位学生 Student stu = listStudent.get(i); //从总课表listChooseCourse中获取该学生的选课记录集合 ArrayList<Message_Box> stuCourseSelects = getStudentSelects(stu.getId()); if (stuCourseSelects.size() != 0) { System.out.println(stu.getId() + " " + stu.getName() + " " + getAvgTotalScore(stuCourseSelects)); } else { System.out.println(stu.getId() + " " + stu.getName() + " " + "did not take any exams"); } } } //获得该学生选课记录的情况下返回该学生的总成绩 private int getAvgTotalScore(ArrayList<Message_Box> stuCourseSelects) { int total = 0; for (Message_Box messageBox : stuCourseSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/stuCourseSelects.size()); } //通过学生的Id查找选课记录表,返回该学生的选课记录 private ArrayList<Message_Box> getStudentSelects(int id) { ArrayList<Message_Box> student_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.student.getId() == id) { student_Message.add(messageBox); } } return student_Message; } public void show_Course() { //按中文拼音进行排序 Collections.sort(listCourse); for (int i = 0 ; i < listCourse.size() ; i++) { //这里的循环是用来遍历每一位课程 Course course = listCourse.get(i); //从总选课记录listCourse中获取该课程的学生信息集合 ArrayList<Message_Box> courseStudentSelects = getcourseStudentSelects(course.getName()); if (courseStudentSelects.size() != 0) { System.out.println(course.getName() + " " + getAvgTotalCourse(courseStudentSelects)); } else { System.out.println(course.getName() + " " + "has no grades yet"); } } } private int getAvgTotalCourse(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/courseStudentSelects.size()); } private ArrayList<Message_Box> getcourseStudentSelects(String name) { ArrayList<Message_Box> course_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.course.getName().equals(name)) { course_Message.add(messageBox); } } return course_Message; } public void show_Classroom() { Collections.sort(listClassroom); for (int i = 0 ; i < listClassroom.size() ; i++) { Classroom classroom = listClassroom.get(i); ArrayList<Message_Box> classroomSelects = getClassSelects(classroom.getClass_ID()); if (classroomSelects.size() != 0) { System.out.println(classroom.getClass_ID() + " " + getAvgTotalClassScore(classroomSelects)); } else { System.out.println(classroom.getClass_ID() + " " + "has no grades yet"); } } } private int getAvgTotalClassScore(ArrayList<Message_Box> classroomSelects) { int total = 0; for (Message_Box messageBox : classroomSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/classroomSelects.size()); } private ArrayList<Message_Box> getClassSelects(int classId) { ArrayList<Message_Box> class_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.student.getId()/100 == classId) { class_Message.add(messageBox); } } return class_Message; } class InputMatching { String Lab_Times_Matching = "[4-9]{1}"; //1个4-9的数字 String stuNumMatching = "[0-9]{8}";//8个0-9的数字 String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String scoreMatching = "([1-9]?[0-9]|100)"; String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String courseTypeMatching = "(选修|必修|实验)"; String checkCourseTypeMatching = "(考试|考察|实验)"; String rate = "^(0(\\.\\d+)?|1(\\.0+)?)$"; //courseInput用于定义课程信息模式(正则表达式) /*这里的正则表达式考虑到了长度为二的情况吗? 这里的测试测试点似乎并不考虑这给error问题*/ String courseInput_1 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; String courseInput_2 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching + " " + rate + " " + rate; String courseInput_3 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching + " " + Lab_Times_Matching; //scoreInput用于定义成绩信息模式(正则表达式) String scoreInput_1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"; String scoreInput_2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching; String scoreInput_3 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching; public int matchingInput(String s) { String[] input = s.split(" "); String Lab_up = ""; String Lab_down = ""; if (input.length >= 4) {//防止报错 Lab_up = input[0] + " " + input[1] + " " + input[2] + " " + input[3]; Lab_down = input[0] + " " + input[1] + " " + input[2]; } if (matchingCourse(s)) {//课程之考试、考察匹配 return 1; } if (matching_Lab(Lab_up)){//课程之实验匹配 for (int i = 4 ; i < input.length ; i++) {//查看后续条件是否符合 if (!input[i].matches(rate)) {//如果找到一个不符合的 return 0; } } return 1; } if (matchingScore(s)) {//成绩之考试、考察 return 2; } if (matching_Score_Lab(Lab_down)) {//成绩之实验 for (int i = 4 ; i < input.length ; i++) {//查看后续条件是否符合 if (!input[i].matches(scoreMatching)) {//如果找到一个不符合的 return 0; } } return 2; } return 0; } private boolean matchingCourse(String s) { String[] ppp = s.split(" "); if (ppp.length==5){ if (ppp[0].matches(courseNameMatching) && ppp[1].matches(courseTypeMatching) && ppp[2].matches(checkCourseTypeMatching) && ppp[3].matches(rate) && ppp[4].matches(rate)){ return true; } } if (s.matches(courseInput_1) || s.matches(courseInput_2)) return true; else return false; } private boolean matchingScore(String s) { if (s.matches(scoreInput_1) || s.matches(scoreInput_2)) return true; else return false; } private boolean matching_Lab (String s) { return s.matches(courseInput_3); } private boolean matching_Score_Lab(String s) { return s.matches(scoreInput_3); } } } class Student implements Comparable<Student>{ private int id; private String name; Student(int id , String name) { this.name = name; this.id = id; } @Override //学号排序 public int compareTo(Student o) { return (this.id - o.getId()); } public int getId() { return id; } public String getName() { return name; } } class Course implements Comparable<Course>{ Course(String name , String Course_Message , String Grade_Way) { this.name = name; this.Course_Message = Course_Message; this.Grade_Way = Grade_Way; } private String name; private String Course_Message; private String Grade_Way; private ArrayList<Double> Weight = new ArrayList<>(); public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(name,o.getName()); } public String getName() { return name; } public String getGrade_Way() { return Grade_Way; } public String getCourse_Message() { return Course_Message; } public void addWeight(double weight) { Weight.add(weight); } public double getWeight(int i) { return Weight.get(i); } public int get_Weight_size(){ return Weight.size(); } } class Classroom implements Comparable<Classroom>{ Classroom(int Id) { this.class_ID = Id; } private int class_ID; @Override public int compareTo(Classroom o) { return this.class_ID - o.getClass_ID(); } public int getClass_ID() { return class_ID; } } class Message_Box { Student student; Course course; // Grade grade; Grade_Course grade_course; Message_Box(Student student , Course course , Grade_Course grade_course) { this.student = student; this.course = course; this.grade_course = grade_course; } } class Grade_Course { ArrayList<Grade_itemize> grade_itemizes = new ArrayList<>(); Grade_Course(Course course, String[] Line) { int num = course.get_Weight_size(); if (num == 1) { grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[3]),course.getWeight(0))); } else if (num == 2) { for (int i = 0 ; i < num ; i++){ grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[i+3]),course.getWeight(i))); } } else if (num >=4 && num <=9){ for (int i = 0 ; i < num ; i++){ grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[i+3]),course.getWeight(i))); } } } public int get_grade_Total() { double total = 0; for (Grade_itemize gradeItemize : grade_itemizes) { total += gradeItemize.get_grade_One(); } return (int)Math.round(total); } } class Grade_itemize { private int score; private double date; Grade_itemize(int score , double date) { this.score = score; this.date = date; } public int getScore() { return score; } public double getDate() { return date; } public double get_grade_One() { return score*date; } }
下面来分析一下代码的逻辑以及各个类的作用:
-
InputMatching类:该类用于匹配输入的字符串,并根据匹配结果判断输入属于课程信息、成绩信息、实验课程还是实验成绩。
-
Student类:表示学生对象,包括学号和姓名属性,并实现了Comparable接口以便进行排序。
-
Course类:表示课程对象,包括课程名称、课程信息和成绩计算方式属性。它还包括一个ArrayList来存储权重,可以根据索引获取每个权重值。也实现了Comparable接口以便进行排序。
-
Classroom类:表示班级对象,只包含班级ID属性。
-
Message_Box类:用于存储学生、课程和成绩信息的封装对象。
-
Grade_Course类:管理课程的成绩项。根据课程的权重和分数创建Grade_itemize对象,并计算课程的总成绩。
-
Grade_itemize类:表示单个成绩项,包括分数和权重。
代码的结构主要是通过类与类之间的关联,来实现程序的功能。例如,Message_Box类中封装了学生、课程和成绩信息,在需要时可以通过访问Message_Box对象来获取这些信息。另外,类之间还实现了Comparable接口来进行排序,如Student和Course类可以根据学号和课程名称进行排序。
踩坑心得:同题目 1 2雷同
改进建议:提取共用的正则表达式模式:在代码中有多个地方使用了正则表达式,可以将共用的模式提取为常量或变量,使其更易于维护和修改。优化字符串拆分:在InputMatching类的matchingInput方法中,通过split方法将字符串拆分为数组。如果输入的字符串较长,这可能会导致性能下降。可以考虑使用更高效的方法,如使用StringTokenizer类或针对特定分隔符的split方法。使用StringBuilder来拼接字符串:在多个地方使用了字符串拼接(如InputMatching类中的Lab_up和Lab_down),可以考虑使用StringBuilder类来提高性能和内存使用效率。引入异常处理:在代码中没有实现异常处理机制。可以考虑使用try-catch块来捕获异常,并对异常进行处理或提供适当的反馈信息给用户。增加注释和文档:为了更好地理解代码的功能和实现方式,可以添加注释和文档,解释每个类、方法和变量的作用,以及代码中的算法思路和数据结构使用。优化代码结构和命名:可以对类、方法和变量的命名进行优化,使其更加清晰、具有描述性。另外,可以考虑重构代码结构,将相关的方法和逻辑进行归类和封装,提高代码的可读性和可维护性。
总结:在其中考试之后,我们将更多的学习重心放在了JAVAFX的学习上,在正则表达式这一类题目上花的时间相对较少,其实正则表达式也是一个比较难的知识点,还有后续的HashMap类等等,就像老师说的,其实这些类都没有ArrayList类好用,用的最多的还是ArrayList类,学习Java最重要的还是把面向过程思想改为面向对象思想。
标签:return,String,int,BLOG3,course,student,public From: https://www.cnblogs.com/cnmdcllbwtmzNB/p/17512434.html