//课程成绩统计程序
import java.util.*; class Course { private String name; private String nature; private String assessment; public Course(String name, String nature, String assessment) { this.name = name; this.nature = nature; this.assessment = assessment; } public String getName() { return name; } public String getNature() { return nature; } public String getAssessment() { return assessment; } } class Student { private String studentId; private String name; private Map<String, Integer> grades; public Student(String studentId, String name) { this.studentId = studentId; this.name = name; this.grades = new HashMap<>(); } public void addGrade(String courseName, int grade) { grades.put(courseName, grade); } public String getStudentId() { return studentId; } public String getName() { return name; } public Map<String, Integer> getGrades() { return grades; } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Course information Map<String, Course> courseMap = new HashMap<>(); // Student information Map<String, Student> studentMap = new TreeMap<>(); // Process input while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); if (line.isEmpty()) { break; } String[] parts = line.split("\\s+"); if (parts.length < 3 || parts.length > 5) { System.out.println("wrong format"); continue; } // Course information input if (parts.length == 3) { String courseName = parts[0]; String nature = parts[1]; String assessment = parts[2]; if (!isValidNature(nature) || !isValidAssessment(assessment)) { System.out.println(courseName + " : course type & access mode mismatch"); continue; } if (courseMap.containsKey(courseName)) { continue; // Ignore duplicate course information } courseMap.put(courseName, new Course(courseName, nature, assessment)); } // Student grade input if (parts.length == 6) { String studentId = parts[0]; String name = parts[1]; String courseName = parts[2]; int midTermGrade = Integer.parseInt(parts[4]); int finalGrade = Integer.parseInt(parts[5]); if (midTermGrade < 0 || midTermGrade > 100 || finalGrade < 0 || finalGrade > 100) { System.out.println("wrong format"); continue; } if (!courseMap.containsKey(courseName)) { System.out.println(studentId + " " + name + " : " + courseName + " does not exist"); continue; } Course course = courseMap.get(courseName); if (!isValidGradeInput(course.getAssessment(), parts.length)) { System.out.println(studentId + " " + name + " : access mode mismatch"); continue; } String courseId = studentId.substring(0, 6); studentMap.putIfAbsent(courseId, new Student(courseId, "")); Student student = studentMap.get(courseId); student.addGrade(courseName, finalGrade); } } // Calculate averages Map<String, Integer> courseAverages = new TreeMap<>(); Map<String, Integer> classAverages = new TreeMap<>(); for (Student student : studentMap.values()) { if (student.getGrades().isEmpty()) { System.out.println(student.getStudentId() + " " + student.getName() + " did not take any exams"); continue; } int totalGrade = 0; for (int grade : student.getGrades().values()) { totalGrade += grade; } int average = totalGrade / student.getGrades().size(); System.out.println(student.getStudentId() + " " + student.getName() + " " + average); String courseId = student.getStudentId(); classAverages.put(courseId, classAverages.getOrDefault(courseId, 0) + average); } for (Course course : courseMap.values()) { if (course.getNature().equals("必修")) { continue; } int midtermSum = 0; int totalSum = 0; int count = 0; for (Student student : studentMap.values()) { if (student.getGrades().containsKey(course.getName())) { int grade = student.getGrades().get(course.getName()); midtermSum += grade; totalSum += grade; count++; } } if (count > 0) { int midtermAverage = midtermSum / count; int totalAverage = totalSum / count; System.out.println(course.getName() + " " + "N/A " + midtermAverage + " " + totalAverage); courseAverages.put(course.getName(), totalAverage); } else { System.out.println(course.getName() + " has no grades yet"); } } for (String courseId : classAverages.keySet()) { int average = classAverages.get(courseId) / studentMap.size(); System.out.println(courseId + " " + average); } } private static boolean isValidNature(String nature) { return nature.equals("必修") || nature.equals("选修"); } private static boolean isValidAssessment(String assessment) { return assessment.equals("考试") || assessment.equals("考察"); } private static boolean isValidGradeInput(String assessment, int gradeInputLength) { if (assessment.equals("考试")) { return gradeInputLength == 6; } else if (assessment.equals("考察")) { return gradeInputLength == 5; } return false; } }
前言:
本次分析的题目是PTA中的"7-1 课程成绩统计程序-1",要求设计一个课程成绩统计程序,根据输入的课程和成绩信息,计算学生的总成绩和各门课程的平均分,并按一定规则输出结果。
设计与分析:
题目要求输入课程和成绩信息,课程信息包括课程名称、课程性质和考核方式;成绩信息包括学号、姓名、课程名称、平时成绩和期末成绩。根据考核方式的不同,计算学生的总成绩和课程的平均分。
首先需要设计数据结构来表示课程和成绩信息。可以使用类来表示课程和成绩,课程类包含课程名称、课程性质和考核方式;成绩类包含学号、姓名、课程名称、平时成绩和期末成绩。通过输入信息构建课程和成绩对象,并存储到相应的数据结构中,如列表或映射等。
然后根据题目要求,对成绩进行计算和统计。根据考核方式的不同,计算学生的总成绩和课程的平均分。对于考试的总成绩,根据平时成绩和期末成绩的权重计算;对于考察的总成绩,直接等于期末成绩。根据学号进行排序,计算学生的总成绩平均分,并按格式输出。同时,计算每门课程的平均分,并按课程名称的字符顺序输出。
最后,根据班级进行统计,计算班级所有课程的总成绩平均分,并按班级号排序输出。
采坑心得:
在实现这个程序时可能会遇到一些问题,比如输入格式错误、成绩超出范围、课程重复等。在处理这些异常情况时,需要仔细检查输入和计算的逻辑,确保程序的正确性。
为了验证程序的正确性,可以编写一些测试用例,包括正常输入和异常输入,检查输出结果是否符合预期。测试用例应该涵盖题目中提到的各种情况,例如输入不匹配、重复的课程信息、重复的成绩信息等。
改进建议:
对于这个题目的编码改进,可以考虑以下几点:
-
提高代码的可读性和可维护性:使用有意义的变量名和函数名,添加必要的注释,采用合适的代码结构和组织方式,使代码更易于理解和修改。
-
引入异常处理机制:在改进中引入异常处理机制,可以提高程序的健壮性和容错性。在输入解析和计算过程中,可以使用try-catch语句捕获可能发生的异常,如格式错误、成绩超出范围等,然后根据具体情况进行相应的错误处理和输出提示信息,而不是简单地将其作为格式错误处理。
-
模块化设计和函数封装:将程序拆分为多个模块和函数,每个函数负责完成特定的功能,提高代码的复用性和可扩展性。例如,可以编写单独的函数来解析输入信息、计算学生总成绩、计算课程平均分等。
-
使用合适的数据结构和算法:根据题目的要求和数据特点,选择适合的数据结构和算法可以提高程序的效率和性能。例如,可以使用哈希表来存储课程信息,以便快速查找和更新;使用排序算法对学生成绩进行排序等。
总结:
通过完成这个题目,我学到了如何设计和分析一个成绩统计程序。在实际编码过程中,我遇到了一些问题,例如处理输入格式错误、异常情况和边界情况的方法,通过解决这些问题,我提高了编程的实践能力和问题解决能力。
在学习过程中,我还意识到自己在某些方面需要进一步学习和研究,比如异常处理机制的使用、更高效的算法和数据结构的选择等。我计划进一步深入学习这些知识,并将其应用于实际的编程项目中。
对于教师、课程、作业、实验、课上及课下组织方式等方面的改进建议和意见,我认为在课程中更加注重实际项目的练习和案例分析会更有助于学生的实际能力提升。此外,希望能提供更多的实践机会和实际问题,以帮助学生更好地理解和应用所学知识。
//容器-HashMap-排序
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Scanner;; public class Main { public static void main(String[] args) { //创建Map集合对象 HashMap<String,Student> map = new HashMap<String, Student>(); List<Student> studentList = new ArrayList<>(); Scanner in = new Scanner(System.in); // 输入学生信息 while (true) { String input = in.nextLine(); if (input.equals("end")) { break; } String[] tokens = input.split(" "); String id = tokens[0]; String name = tokens[1]; int score = Integer.parseInt(tokens[2]);//将字符串类型的成绩转换为整数类型的成绩 Student student = new Student(id, name, score); map.put(id, student); studentList.add(student); } // // 根据学号检索学生信息 // String studentId = in.nextLine(); // Student result = map.get(studentId); // if (result != null) { // System.out.println(result.getStudentInfo()); // } else { // System.out.println("The student " + studentId + " does not exist"); // } // 根据学号排序学生信息 Collections.sort(studentList, new Comparator<Student>() { public int compare(Student s1, Student s2) { return s2.getId().compareTo(s1.getId());//学号从大到小排序,若将s1与s2互换,则从小到大排序 } }); // 遍历排序后的学生列表并输出信息 for (Student student : studentList) { System.out.println(student.getStudentInfo()); } } } 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 getStudentInfo() { return id + " " + name + " " + score; } }
前言:
本题目要求设计一个程序,使用HashMap存储学生的成绩信息,并按照学号从大到小的顺序输出所有学生的信息。
设计与分析:
题目要求使用HashMap来存储学生的成绩信息,其中学号作为键(key),姓名和成绩作为值(value)。由于学号是唯一的,适合作为HashMap的键。
首先,需要设计数据结构来表示学生的成绩信息。可以使用一个HashMap对象来存储学生信息,键为学号(String类型),值为一个自定义的类(例如Student类),该类包含学生的姓名(String类型)和成绩(int类型)。
然后,通过循环读取输入,解析学生的成绩信息,并将学生信息存储到HashMap中。在读取输入时,以"end"为结束标志。
接下来,对HashMap中的学生信息进行排序。由于题目要求按学号从大到小排序,可以将HashMap中的键值对转换为ArrayList,并使用Collections类的sort方法进行排序。排序时,可以自定义一个Comparator来比较学生的学号,实现按学号从大到小排序。
最后,按照排序后的顺序输出所有学生的信息。遍历排序后的ArrayList,获取每个学生的学号、姓名和成绩,按照指定格式输出。
采坑心得:
在实现这个程序时,可能会遇到一些问题。例如,如何正确解析输入的学生信息,如何使用HashMap存储和排序学生信息等。
在处理输入时,需要注意输入格式的正确性,确保学号、姓名和成绩的正确解析。同时,还要考虑到可能出现重复的姓名的情况,因为题目中并没有规定姓名是唯一的。
在使用HashMap存储学生信息时,需要确保学号作为键的唯一性,可以在添加学生信息时进行判断,避免重复的学号。
在对HashMap中的学生信息进行排序时,可以将键值对转换为ArrayList,并自定义Comparator来比较学号的大小,实现排序。
改进建议:
对于这个题目的编码改进,可以考虑以下几点:
-
错误处理:在解析输入和操作HashMap时,考虑可能出现的异常情况,如输入格式错误、重复的学号等,可以使用try-catch语句捕获异常并进行相应的错误处理。
-
封装学生类:将学生的学号、姓名和成绩封装为一个Student类,提供合适的构造方法和访问方法,提高代码的可读性和可维护性。
-
使用泛型:在定义HashMap时,可以使用泛型来指定键和值的类型,增加程序的类型安全性。
-
单一职责原则:将输入解析、HashMap操作和排序等功能拆分为不同的函数或
模块,每个模块负责完成特定的功能,提高代码的可读性和可维护性。
- 性能优化:对于大量学生信息的情况,可以考虑使用更高效的数据结构和算法来存储和排序,例如使用TreeMap或自定义的平衡二叉树来替代HashMap,并实现自动排序的功能。
总结:
-
通过完成这个题目,我学到了如何使用HashMap存储学生信息,并按学号排序输出。在实际编码过程中,我遇到了一些问题,如输入解析、HashMap的操作和排序等,通过解决这些问题,我提高了编程的实践能力和问题解决能力。
在学习过程中,我还意识到自己在一些方面需要进一步学习和研究,如异常处理机制的使用、高效的数据结构和算法等。我计划进一步深入学习这些知识,并将其应用于实际的编程项目中。