(1).前言:(总结之前所涉及到的知识点、题量、难度等情况)
一 7-1 课程成绩统计程序-1
难度:对我来说,难,难,难,写这个我花了好长时间,分析了很久很久,但是要比较的话,菜单要更难,还是我太菜了。
知识点:
1. 集合类:代码使用了多种集合类,如'ArrayList'、'HashMap'和'LinkedHashMap',用于存储和管理不同的数据对象,'HashMap'和'LinkedHashMap'是Java中的两种常见的哈希映射实现类,它们都实现了'Map'接口,用于存储。
2. 迭代器:迭代器来遍历集合类中的元素,例如使用'Iterator'接口来遍历'HashMap'中的值。
3. 异常处理:异常处理机制来捕获和处理可能发生的异常情况。例如,在计算平均值时,如果没有成绩可用,代码会抛出'ArithmeticException'异常。
4.字符串处理:代码使用字符串的相关方法,如'split()'用于拆分字符串,'matches()'用于匹配正则表达式。matches()
方法:该方法用于检查字符串是否与指定的正则表达式匹配。在代码中,matches()
方法被用于验证输入的字符串是否符合特定的模式
5. 排序:使用'Comparator'接口来实现自定义的比较器,并使用'sort()'方法对集合进行排序,使用'Collator'类进行字符串比较和排序,可以根据不同的区域设置进行字符串排序。
二 7-2 课程成绩统计程序-2
难度:由于我的 课程成绩统计程序-1写的有点太死板,所以我改的崩溃,在我原来的代码的初上基础上改了很久,最后还是换了一种思路,重新写了。不过确实要跟简单一些。
知识点:(和上面差不多)
1。排序和比较操作,通过调用 sort
方法和实现 Comparator
接口,对学生、课程和班级进行排序。此外,使用 Collator
类对中文字符串进行比较
2.使用了字符串的处理方法,如 split
方法将输入字符串按空格分割为数组,substring
方法截取子字符串等。
substring
方法是字符串类(String
)提供的一个方法,用于截取子字符串。它有两种重载形式:
-
substring(int beginIndex)
: 从指定的索引位置beginIndex
(包括该索引位置的字符)开始,截取到字符串的末尾,并返回截取得到的子字符串。 -
substring(int beginIndex, int endIndex)
: 从指定的索引位置beginIndex
(包括该索引位置的字符)开始,截取到索引位置endIndex
(不包括该索引位置的字符)为止,并返回截取得到的子字符串。
三 7-3 课程成绩统计程序-3
难度:这次我没有花很长时间,因为我在狂补我要命的离散,写了一下,感觉以我的实力肯定又要写好久,拿了及格分就没管了(错误行为),还是有难度的吧
知识点:和1.2雷同
(2) 设计与分析:重点对题目的提交源码进行分析(由于上次我把题目放上来,有同学说这是水字数太伤心了,我这次就放一个题目,其他直接分析代码啦)
一 7-1 课程成绩统计程序-1
7-1 课程成绩统计程序-1 分数 100 作者 蔡轲 单位 南昌航空大学某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃
我的代码
import java.text.Collator; import java.util.*; class Course { public String name; public String type; public String assessment; public Boolean selected; public HashMap<String, Score> scores; public Course(String name, String type, String assessment) { this.name = name; this.type = type; this.assessment = assessment; this.selected = false; this.scores = new HashMap<>(); } public int getRegularMean() { int score = 0; Iterator<Score> it = scores.values().iterator(); while (it.hasNext()) { score += it.next().regularScore; } return (int) (score / scores.size()); } public int getFinalMean() { int score = 0; Iterator<Score> it = scores.values().iterator(); while (it.hasNext()) { score += it.next().finalScore; } return (int) (score / scores.size()); } public int getTotalMean() { int score = 0; Iterator<Score> it = scores.values().iterator(); while (it.hasNext()) { score += it.next().getScore(); } return (int) (score / scores.size()); } } class Student { public String studentId; public String studentName; public HashMap<String, Score> scores; public Student(String studentId, String studentName) { this.studentId = studentId; this.studentName = studentName; this.scores = new HashMap<>(); } public int mean() throws ArithmeticException { int score = 0; Iterator<Score> it = scores.values().iterator(); while (it.hasNext()) { score += it.next().getScore(); } return (int) (score / scores.size()); } } class _Class { public String classId; public ArrayList<Student> students; public _Class(String classId) { this.classId = classId; this.students = new ArrayList<>(); } public void push(Student student) { students.add(student); } public int mean() throws ArithmeticException { int score = 0; int flag = 0; for (Student student : students) { if (!student.scores.isEmpty()){ score += student.mean(); flag = 1; } } if (flag == 0) throw new ArithmeticException(); return (int) (score / students.size()); } } abstract class Score { public int regularScore; public int finalScore; public Score(int regularScore, int finalScore) { this.regularScore = regularScore; this.finalScore = finalScore; } public abstract int getScore(); } class InvestigateScore extends Score { public InvestigateScore(int regularScore, int finalScore) { super(regularScore, finalScore); } @Override public int getScore() { return super.finalScore; } } class ExamineScore extends Score { public ExamineScore(int regularScore, int finalScore) { super(regularScore, finalScore); } @Override public int getScore() { return (int) (super.finalScore * 0.7 + super.regularScore * 0.3); } } public class Main { public static void main(String[] args) { ArrayList<String> inputs = new ArrayList<>(); Scanner scanner = new Scanner(System.in); while(true) { String buffer = scanner.nextLine(); if (buffer.equals("end")) break; inputs.add(buffer); } scanner.close(); ArrayList<String> outputs = new ArrayList<>(); ArrayList<String> errors = new ArrayList<>(); HashMap<String, Course> courseMap = new LinkedHashMap<>(); HashMap<String, Student> studentMap = new LinkedHashMap<>(); HashMap<String, _Class> classMap = new LinkedHashMap<>(); for (String input : inputs) { String[] parameters = input.split(" "); int len = parameters.length; try { if (len == 3) { String name = parameters[0]; String type = parameters[1]; String assessment = parameters[2]; Course course = new Course(name, type, assessment); if (Collator.getInstance(Locale.CHINA).compare(course.type, "选修") != 0 && Collator.getInstance(Locale.CHINA).compare(course.type, "必修") != 0) { errors.add("wrong format"); continue; } if (Collator.getInstance(Locale.CHINA).compare(course.assessment, "考察") != 0 && Collator.getInstance(Locale.CHINA).compare(course.assessment, "考试") != 0) { errors.add("wrong format"); continue; } if (Collator.getInstance(Locale.CHINA).compare(course.assessment, "考察") == 0 && Collator.getInstance(Locale.CHINA).compare(course.type, "必修") == 0) { errors.add(course.name + " : course type & access mode mismatch"); continue; } if (!courseMap.containsKey(name)) { courseMap.put(name, course); } } else if (len == 4) { String studentId = parameters[0]; if (!studentId.matches("\\d+")) { errors.add("wrong format"); continue; } if (studentId.length() != 8) { errors.add("wrong format"); continue; } String classId = studentId.substring(0, 6); String studentName = parameters[1]; if (studentName.length() >= 10) { errors.add("wrong format"); continue; } String courseName = parameters[2]; if (courseName.length() >= 10) { errors.add("wrong format"); continue; } int finalScore = Integer.parseInt(parameters[3]); InvestigateScore investigateScore = new InvestigateScore(0, finalScore); Student student = null; if (!studentMap.containsKey(studentId)) { student = new Student(studentId, studentName); } else { student = studentMap.get(studentId); } Course course = courseMap.get(courseName); if (course == null) { errors.add(courseName + " does not exist"); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); continue; } if (Collator.getInstance(Locale.CHINA).compare(course.assessment, "考试") == 0) { errors.add(studentId + " " + studentName + " : access mode mismatch"); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); continue; } if (finalScore > 100 || finalScore < 0) { errors.add("wrong format"); continue; } if (course.scores.containsKey(studentName)) { continue; } course.selected = true; course.scores.put(studentName, investigateScore); courseMap.put(courseName, course); student.scores.put(course.name, investigateScore); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); } else if (len == 5) { String studentId = parameters[0]; if (!studentId.matches("\\d+")) { errors.add("wrong format"); continue; } if (studentId.length() != 8) { errors.add("wrong format"); continue; } String classId = studentId.substring(0, 6); String studentName = parameters[1]; if (studentName.length() >= 10) { errors.add("wrong format"); continue; } String courseName = parameters[2]; if (courseName.length() >= 10) { errors.add("wrong format"); continue; } int regularScore = Integer.parseInt(parameters[3]); int finalScore = Integer.parseInt(parameters[4]); ExamineScore examineScore = new ExamineScore(regularScore, finalScore); Student student = null; if (!studentMap.containsKey(studentId)) { student = new Student(studentId, studentName); } else { student = studentMap.get(studentId); } Course course = courseMap.get(courseName); if (course == null) { errors.add(courseName + " does not exist"); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); continue; } if (Collator.getInstance(Locale.CHINA).compare(course.assessment, "考察") == 0) { errors.add(studentId + " " + studentName + " : access mode mismatch"); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); continue; } if (regularScore > 100 || regularScore < 0) { errors.add("wrong format"); continue; } if (finalScore > 100 || finalScore < 0) { errors.add("wrong format"); continue; } if (course.scores.containsKey(studentName)) { continue; } course.selected = true; course.scores.put(studentName, examineScore); courseMap.put(courseName, course); student.scores.put(course.name, examineScore); studentMap.put(studentId, student); _Class _class = classMap.containsKey(classId) ? classMap.get(classId) : new _Class(classId); _class.students.add(student); classMap.put(classId, _class); } else { errors.add("wrong format"); } } catch (Exception e) { errors.add("wrong format"); } } ArrayList<Course> courses = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); ArrayList<_Class> classes = new ArrayList<>(); courseMap.forEach((key, value) -> { courses.add(value); }); studentMap.forEach((key, value) -> { students.add(value); }); classMap.forEach((key, value) -> { classes.add(value); }); students.sort(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return s1.studentId.compareTo(s2.studentId); } }); courses.sort(new Comparator<Course>() { @Override public int compare(Course c1, Course c2) { return Collator.getInstance(Locale.CHINA).compare(c1.name, c2.name); } }); classes.sort(new Comparator<_Class>() { @Override public int compare(_Class c1, _Class c2) { return c1.classId.compareTo(c2.classId); } }); ArrayList<String> studentScore = new ArrayList<>(); for (Student student : students) { if (student.scores.isEmpty()) { studentScore.add(student.studentId + " " + student.studentName + " did not take any exams"); } else { studentScore.add(student.studentId + " " + student.studentName + " " + student.mean()); } } ArrayList<String> courseScore = new ArrayList<>(); for (Course course : courses) { if (!course.scores.isEmpty()) { if (Collator.getInstance(Locale.CHINA).compare(course.assessment, "考试") == 0) { courseScore.add(course.name + " " + course.getRegularMean() + " " + course.getFinalMean() + " " + course.getTotalMean()); } else { courseScore.add(course.name + " " + course.getFinalMean() + " " + course.getTotalMean()); } } else { courseScore.add(course.name + " has no grades yet"); } } ArrayList<String> classScore = new ArrayList<>(); for (_Class _class : classes) { try { classScore.add(_class.classId + " " + _class.mean()); } catch (ArithmeticException e) { classScore.add(_class.classId + " has no grades yet"); } } outputs.addAll(errors); outputs.addAll(studentScore); outputs.addAll(courseScore); outputs.addAll(classScore); for (String output : outputs) { System.out.println(output); } } }
分析:
这份代码我写的挺久的,查了很多资料,超级认真,但是后来我才发现我的代码太复杂了,如果要改的话很复杂,按照老师给我们提示的类图一步步的划分,有七个类,如下:
-
Course
类:表示课程,具有课程名称、类型、评估方式、选修状态和成绩的属性。它包含了计算正常考试平均成绩、期末考试平均成绩和总平均成绩的方法。 -
Student
类:表示学生,具有学生ID、姓名和成绩的属性。它包含了计算平均成绩的方法。 -
_Class
类:表示班级,具有班级ID和学生列表的属性。它包含了计算班级平均成绩的方法。 -
Score
抽象类:表示成绩,包含正常考试成绩和期末考试成绩的属性。它是一个抽象类,需要子类进行扩展,并实现获取成绩的抽象方法。 -
InvestigateScore
类:表示考察成绩,继承自Score 类,实现了获取成绩的方法。 -
ExamineScore
类:表示考试成绩,也是继承自Score 类,实现了获取成绩的方法。 -
Main
类:包含程序的入口方法 。它通过用户输入来管理课程、学生和班级的成绩信息。程序首先读取用户输入的信息,然后根据输入执行相应的操作,如创建课程、学生、成绩等。最后,程序根据输入的信息计算并输出学生、课程和班级的平均成绩。 -
还有就是我通过创建并初始化一些数据结构,如课程映射表 、学生映射表 和班级映射表 。
courseMap
studentMap
classMap。
通过循环读取用户输入的信息,并根据输入的指令进行相应的操作,输入的信息包括课程信息、学生信息和成绩信息,根据输入的信息,程序会创建相应的课程对象、学生对象和成绩对象,并将它们添加到对应的数据结构中。在处理输入信息的过程中,会检查输入的格式是否正确,例如判断学生ID的格式、课程名称的长度等。如果发现格式错误,程序会将错误信息添加到error 列表中。完成输入信息的处理后,程序会对学生、课程和班级进行排序,并计算并输出平均成绩。具体的计算和排序方式可以参考代码中的实现。最后,程序会将输出信息逐行打印到控制台。需要注意的是,这个程序对输入的格式进行了一定的校验,如果发现格式错误,会将错误信息添加到errors
列表中,并在最后的输出中显示错误
类图
难度分析图
二 7-2 课程成绩统计程序-2
我的代码
public void parseInput(String input){ String []inputs=input.split(" "); if(InputMatching.matchingInput(input)==1){ courseMethod.put(inputs[0],inputs[2]); if(checkCourse(inputs[0])!=null)return; else { if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){ System.out.println(inputs[0]+" : course type & access mode mismatch"); } else if(inputs[1].equals("选修")&&!(inputs[2].equals("考试")||inputs[2].equals("考察"))){ System.out.println(inputs[0]+" : course type & access mode mismatch"); } else if(inputs[1].equals("实验")&&!(inputs[2].equals("实验"))){ System.out.println(inputs[0]+" : course type & access mode mismatch"); } else courses.add(new Course(inputs[0],inputs[1],inputs[2])); } } else if(InputMatching.matchingInput(input)==2){ Course findcourse=checkCourse(inputs[2]); if(inputs.length>5&&(Integer.parseInt(inputs[3])<4||Integer.parseInt(inputs[3])>9)) { System.out.println("wrong format"); return; } Student newStudent = new Student(inputs[0],inputs[1]); if(!checkStudent(newStudent.getNum()))students.add(newStudent); if(!checkClass(inputs[0].substring(0,6))){ Class.add(inputs[0].substring(0,6)); } if(checkSelect(inputs[0],inputs[2]))return; if(findcourse==null){ System.out.println(inputs[2]+" does not exist"); return; } else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){ System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch"); } else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){ System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch"); } else if(findcourse.getMethod().equals("实验")&&(inputs.length-4!=Integer.parseInt(inputs[3]))){ System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch"); } else{ SelectCourse newSelectCourse=new SelectCourse(); newSelectCourse.setCourse(findcourse); Grade grade=null; if(findcourse.getMethod().equals("考试")){ ExamGrade examGrade=new ExamGrade(); examGrade.setUsualGrade(Integer.parseInt(inputs[3])); examGrade.setFinalGrade(Integer.parseInt(inputs[4])); grade=examGrade; } else if(findcourse.getMethod().equals("实验")){ NoExamGrade noExamGrade=new NoExamGrade(); double sumScore=0; for (int i=4;i<inputs.length;i++)sumScore+=Integer.parseInt(inputs[i]); noExamGrade.setFinalGrade((int)(sumScore/Integer.parseInt(inputs[3]))); grade=noExamGrade; } else { NoExamGrade noExamGrade=new NoExamGrade(); noExamGrade.setFinalGrade(Integer.parseInt(inputs[3])); grade=noExamGrade; } newSelectCourse.setGrade(grade); newSelectCourse.setStudent(newStudent); selectCourses.add(newSelectCourse); } } else System.out.println("wrong format"); } private Course checkCourse(String courseName){ for (Course course:courses){ if(course.getName().equals(courseName))return course; } return null; } private Boolean checkStudent(String num){ for (Student student:students){ if(student.getNum().equals(num))return true; } return false; } private Boolean checkClass(String classnum){ for (String cname:Class){ if(cname.equals(classnum))return true; } return false; } private Boolean checkSelect(String stunum,String cname){ for (SelectCourse selectCourse:selectCourses){ if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true; } return false; } public void studentScore(){ for (Student student:students){ double sum=0; int count=0; for (SelectCourse selectCourse:selectCourses){ if (selectCourse.getStudent().getNum().equals(student.getNum())) { sum+=selectCourse.getGrade().getTotalGrade(); count++; } } if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams"); else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count)); } } public void CourseScore(){ for (Course course:courses){ double sumUsualScore=0; double sumFinalScore=0; double sumTotalScore=0; int count=0; for(SelectCourse selectCourse:selectCourses){ if(selectCourse.getCourse().getName().equals(course.getName())){ count++; sumTotalScore+=selectCourse.getGrade().getTotalGrade(); sumFinalScore+=selectCourse.getGrade().getFinalGrade(); if(selectCourse.getCourse().getMethod().equals("考试")){ sumUsualScore+=selectCourse.getGrade().getUsualGrade(); } } } if (count==0) System.out.println(course.getName()+' '+"has no grades yet"); else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count)); else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count)); else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)); } } public void ClassScore(){ for (String classnum:Class){ double sum=0; int count=0; for (SelectCourse selectCourse:selectCourses){ if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){ sum+=selectCourse.getGrade().getTotalGrade(); count++; } } if(count==0) System.out.println(classnum+' '+"has no grades yet"); else System.out.println(classnum+' '+(int)(sum/count)); } } public void MySort(){ students.sort(Comparator.comparing(Student::getNum)); courses.sort((x,y)->{ Collator instance = Collator.getInstance(Locale.CHINA); return instance.compare(x.getName(), y.getName()); } ); Collections.sort(Class); } } abstract class Grade{ double TotalGrade; public int getTotalGrade() { return (int) TotalGrade; } public int getUsualGrade() { return 0; } public int getFinalGrade() { return 0; } } class ExamGrade extends Grade{ int UsualGrade; int FinalGrade; public int getTotalGrade(){ return (int)(0.3*this.getUsualGrade()+0.7*this.getFinalGrade()); } public int getUsualGrade() { return UsualGrade; } public void setUsualGrade(int usualGrade) { UsualGrade = usualGrade; } public int getFinalGrade() { return FinalGrade; } public void setFinalGrade(int finalGrade) { FinalGrade = finalGrade; } } class NoExamGrade extends Grade{ int FinalGrade; public int getTotalGrade(){ return FinalGrade; } public int getFinalGrade() { return FinalGrade; } public void setFinalGrade(int finalGrade) { FinalGrade = finalGrade; } } class Course{ String name; String kind; String method; public Course(String name, String kind, String method) { this.name = name; this.kind = kind; this.method = method; } public String getName() { return name; } public String getMethod() { return method; } } class Student{ String num; String name; public Student(String num, String name) { this.num = num; this.name = name; } public String getNum() { return num; } public String getName() { return name; } } class SelectCourse{ Course course; Student student; Grade grade; public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } } class InputMatching { static String stuNumMatching = "[0-9]{8}"; static String stuNameMatching = "\\S{1,10}"; static String scoreMatching = "(\\d|[1-9]\\d|100)"; static String courseNameMatching = "\\S{1,10}"; static String courseTypeMatching = "(选修|必修|实验)"; static String checkcourseTypeMatching = "(考试|考察|实验)"; static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching; static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(\\s"+scoreMatching+")*"; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s)) { return 2; } return 0; } private static boolean matchingCourse(String s) { return s.matches(courseInput); } private static boolean matchingScore(String s) { return s.matches(scoreInput); } }
分析:我更改了一下类。
在main方法中,通过Scanner类获取用户输入,并创建一个ParseInput对象来处理输入数据。 ParseInput类是用于解析输入数据的辅助类。它包含了用于存储课程、学生、选课和班级信息的列表和哈希表。parseInput方法根据输入的格式进行解析,并将解析后的数据存储到相应的数据结构中。 Course类表示课程,包含名称、类型和访问方式等属性。 Student类表示学生,包含学号和姓名等属性。 Grade类是一个抽象类,表示成绩。它有一个抽象方法getTotalGrade,用于计算总成绩。 ExamGrade和NoExamGrade类继承自Grade类,分别表示考试成绩和非考试成绩。 SelectCourse类表示选课,包含课程、学生和成绩等属性。 InputMatching类用于验证输入数据的格式是否正确。 MySort方法用于对学生、课程和班级进行排序。 studentScore方法用于计算并输出每个学生的平均成绩。 CourseScore方法用于计算并输出每门课程的平均成绩。 ClassScore方法用于计算并输出每个班级的平均成绩。
Main
:主类,包含了程序的入口方法main
,负责读取输入并调用相关方法进行处理。2.ParseInput
:解析输入类,包含了解析输入的方法和一些辅助方法,用于解析和处理输入数据。Grade
:成绩抽象类,作为成绩的父类,包含了抽象方法和一些通用属性。ExamGrade
:考试成绩类,继承自Grade
,表示考试类成绩,包含了具体的成绩计算方法和属性。NoExamGrade
:非考试成绩类,继承自Grade
,表示非考试类成绩,包含了具体的成绩计算方法和属性。Course
:课程类,表示一门课程,包含了课程的名称、类型和访问方式等属性。Student
:学生类,表示一个学生,包含了学生的学号和姓名等属性。SelectCourse
:选课类,表示学生选修的一门课程,包含了课程、学生和成绩等属性。- 此外,还有一个辅助类
InputMatching
,用于判断输入的格式是否符合要求。
代码的主要逻辑是通过解析输入数据,创建课程、学生和选课关系,并计算和输出学生、课程和班级的成绩统计信息
类图:
难度分析图
三 7-3 课程成绩统计程序-3
我的代码
import java.util.*; public class Main { public static void main(String[] args) { Scanner s = new Scanner(System.in); String s_record = s.nextLine(); ParseInput handle=new ParseInput(); while (!s_record.equals("end")) { handle.parseInput(s_record); s_record = s.nextLine(); } handle.MySort(); handle.studentScore(); handle.CourseScore(); handle.ClassScore(); } } class ParseInput{ private final ArrayList<SelectCourse> selectCourses = new ArrayList<>(); private HashMap<String, Course> courses = new HashMap<>(); private final ArrayList<Student> students = new ArrayList<>(); private final ArrayList<String> Class = new ArrayList<>(); private final HashMap<String,String> courseMethod=new HashMap(); public void parseInput(String input) { String[] inputs = input.split(" "); if (InputMatching.judge(input) == 1) { if (courses.containsKey(inputs[0])) return; else { Course newCourse = new Course(inputs[0], inputs[1], inputs[2]); double totalWeight = 0; switch (inputs[2]) { case "考试": if (inputs.length != 5) { System.out.println("wrong format"); return; } totalWeight = Double.parseDouble(inputs[3]) + Double.parseDouble(inputs[4]); if (totalWeight != 1) { System.out.println(inputs[0] + " : weight value error"); return; } List<Double> weightList = new ArrayList<>(); weightList.add(Double.parseDouble(inputs[3])); weightList.add(Double.parseDouble(inputs[4])); newCourse.setWeightList(weightList); break; case "考察": if (inputs.length != 3) { System.out.println("wrong format"); return; } break; case "实验": if (inputs.length < 5 || (inputs.length - 4) != Integer.parseInt(inputs[3])) { System.out.println(inputs[0] + " : number of scores does not match"); return; } if (Integer.parseInt(inputs[3]) < 4 || Integer.parseInt(inputs[3]) > 9) { System.out.println(inputs[0] + " : number of scores does not match"); return; } List<Double> weightList1 = new ArrayList<>(); for (int i = 4; i < inputs.length; i++) { totalWeight += Double.parseDouble(inputs[i]); weightList1.add(Double.parseDouble(inputs[i])); } if (totalWeight != 1) { System.out.println(inputs[0] + " : weight value error"); return; } newCourse.setWeightList(weightList1); break; default: System.out.println(inputs[0] + " : course type & access mode mismatch"); return; } // newCourse.getWeightList().forEach(System.out::println); courses.put(inputs[0], newCourse); } } else if (InputMatching.matchingInput(input) == 2) { Course findcourse = courses.get(inputs[2]); if (findcourse == null) { System.out.println(inputs[0] + ' ' + inputs[1] + " : " + inputs[2] + " does not exist"); return; } String courseName = findcourse.getName(); String courseType = findcourse.getMethod(); if (!courseName.equals(inputs[2])) { System.out.println(inputs[0] + ' ' + inputs[1] + " : " + inputs[2] + " does not exist"); return; } Student newStudent = new Student(inputs[0], inputs[1]); if (!checkStudent(newStudent.getNum())) students.add(newStudent); if (!checkClass(inputs[0].substring(0, 6))) { Class.add(inputs[0].substring(0, 6)); } if (checkSelect(inputs[0], inputs[2])) return; if (findcourse.getMethod().equals("考试") && inputs.length != 5) { System.out.println(inputs[0] + ' ' + inputs[1] + " : access mode mismatch"); } else if (findcourse.getMethod().equals("考察") && inputs.length != 4) { System.out.println(inputs[0] + ' ' + inputs[1] + " : access mode mismatch"); }else if (findcourse.getMethod().equals("实验") && inputs.length != 3 + findcourse.getWeightList().size()) { System.out.println(inputs[0] + ' ' + inputs[1] + " : access mode mismatch"); } else { SelectCourse newSelectCourse = new SelectCourse(); newSelectCourse.setCourse(findcourse); Grade grade = null; if (findcourse.getMethod().equals("考试")) { ExamGrade examGrade = new ExamGrade(); if (Integer.parseInt(inputs[3]) < 0 || Integer.parseInt(inputs[3]) > 100 || Integer.parseInt(inputs[4]) < 0 || Integer.parseInt(inputs[4]) > 100) { System.out.println("wrong format"); return; } examGrade.setUsualGrade(Double.parseDouble(inputs[3])); examGrade.setFinalGrade(Double.parseDouble(inputs[4])); examGrade.setUsualWeight(findcourse.getWeightList().get(0)); examGrade.setFinalWeight(findcourse.getWeightList().get(1)); grade = examGrade; } else if (findcourse.getMethod().equals("实验")) { WeightedGrade weightedGrade = new WeightedGrade(); ArrayList<Double> weightList = new ArrayList<>(); ArrayList<Double> scoreList = new ArrayList<>(); double sumScore = 0; for (int i = 3; i < inputs.length; i++) { if (Double.parseDouble(inputs[i]) < 0 || Double.parseDouble(inputs[i]) > 100) { System.out.println("wrong format"); return; } sumScore += Double.parseDouble(inputs[i]) * findcourse.getWeightList().get(i - 3); scoreList.add(Double.parseDouble(inputs[i])); weightList.add(findcourse.getWeightList().get(i - 3)); } weightedGrade.setScoreList(scoreList); weightedGrade.setWeightList(weightList); weightedGrade.setFinalGrade(sumScore); grade = weightedGrade; } else { NoExamGrade noExamGrade = new NoExamGrade(); noExamGrade.setFinalGrade(Integer.parseInt(inputs[3])); grade = noExamGrade; } newSelectCourse.setGrade(grade); newSelectCourse.setStudent(newStudent); selectCourses.add(newSelectCourse); } } else { System.out.println("wrong format"); } } private Course checkCourse(String courseName){ return courses.get(courseName); } private Boolean checkStudent(String num){ for (Student student:students){ if(student.getNum().equals(num))return true; } return false; } private Boolean checkClass(String classnum){ for (String cname:Class){ if(cname.equals(classnum))return true; } return false; } private Boolean checkSelect(String stunum,String cname){ for (SelectCourse selectCourse:selectCourses){ if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true; } return false; } public void studentScore(){ for (Student student:students){ double sum=0; int count=0; for (SelectCourse selectCourse:selectCourses){ if (selectCourse.getStudent().getNum().equals(student.getNum())) { // System.out.println(selectCourse.getCourse().getName()+' '+selectCourse.getGrade().getTotalGrade()); sum+=selectCourse.getGrade().getTotalGrade(); count++; } } if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams"); // 小数部分直接舍去,不四舍五入 else System.out.println(student.getNum()+' '+student.getName()+' '+(int)sum/count); } } public void CourseScore(){ for (Course course:courses.values()){ double sumUsualScore=0; double sumFinalScore=0; double sumTotalScore=0; int count=0; for(SelectCourse selectCourse:selectCourses){ if(selectCourse.getCourse().getName().equals(course.getName())){ count++; sumTotalScore+=selectCourse.getGrade().getTotalGrade(); sumFinalScore+=selectCourse.getGrade().getFinalGrade(); if(selectCourse.getCourse().getMethod().equals("考试")){ sumUsualScore+=selectCourse.getGrade().getUsualGrade(); } } } if (count==0) System.out.println(course.getName()+' '+"has no grades yet"); // 四舍五入 保留整数 else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count) + ' '+(int)(sumFinalScore/count) + ' '+(int)(sumTotalScore/count)); else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumTotalScore/count) + ' '+(int)(sumFinalScore/count)); else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+ (int)(sumTotalScore/count)); } } public void ClassScore(){ for (String classnum:Class){ double sum=0; int count=0; for (SelectCourse selectCourse:selectCourses){ if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){ sum+=selectCourse.getGrade().getTotalGrade(); count++; } } if(count==0) System.out.println(classnum+' '+"has no grades yet"); else System.out.println(classnum+' '+(int)sum/count); } } public void MySort() { students.sort(Comparator.comparing(Student::getNum)); List<Map.Entry<String, Course>> courseList = new ArrayList<>(courses.entrySet()); courseList.sort(Map.Entry.comparingByValue(Comparator.comparing(Course::getName))); HashMap<String, Course> sortedCourses = new LinkedHashMap<>(); for (Map.Entry<String, Course> entry : courseList) { sortedCourses.put(entry.getKey(), entry.getValue()); } courses = sortedCourses; Class.sort(String::compareTo); selectCourses.sort((a, b) -> { int compareStudents = a.getStudent().getNum().compareTo(b.getStudent().getNum()); if (compareStudents != 0) { return compareStudents; } else { return a.getCourse().getName().compareTo(b.getCourse().getName()); } }); } } class InputMatching { static String stuNumMatching = "[0-9]{8}"; static String stuNameMatching = "\\S{1,10}"; static String scoreMatching = "(\\d|[1-9]\\d|100)"; static String courseNameMatching = "\\S{1,10}"; static String courseTypeMatching = "(选修|必修|实验)"; static String weightMatching = "(0\\.[0-9]+|1\\.0)(\\s(0\\.[0-9]+|1\\.0))*"; static String checkcourseTypeMatching = "(考试|考察|实验)"; static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching + "(\\s\\d+\\s" + weightMatching + ")?"; static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(\\s"+scoreMatching+")*"; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s)) { return 2; } return 0; } public static int judge(String a) { String[]arr=a.split(" "); int len=arr.length; if(len==3&&arr[0].length()<=10&&arr[1].matches("^(必修)|(选修)|(实验)$")&&arr[2].matches("^(考试)|(考察)|(实验)$")) return 1; else if(arr[0].length()<=10&&arr[1].matches("^(必修)|(选修)|(实验)$")&&arr[2].matches("^(考试)|(考察)|(实验)$")&&arr[3].matches("^[4-9]$")) { boolean flag=true; if(flag) return 1; } else if(len==5&&arr[0].length()<=10&&arr[1].matches("^(必修)|(选修)|(实验)$")&&arr[2].matches("^(考试)|(考察)|(实验)$")) { boolean flag=true; if(flag) return 1; } else if(arr[0].matches("^[0-9]{8}$")&&arr[1].length()<=10&&arr[2].length()<=10) { boolean flag=true; for(int i=0;i<len-3;i++) { if(!arr[3+i].matches("^[0-9]{1,2}|100$")) { flag=false; break; } } if(flag) return 2; } return 0; } private static boolean matchingCourse(String s) { return s.matches(courseInput); } private static boolean matchingScore(String s) { return s.matches(scoreInput); } } abstract class Grade{ double TotalGrade; public double getTotalGrade() { return TotalGrade; } public double getUsualGrade() { return 0; } public double getFinalGrade() { return 0; } } class ExamGrade extends Grade{ double UsualGrade; double FinalGrade; double UsualWeight; double FinalWeight; public double getTotalGrade(){ return UsualGrade*UsualWeight+FinalGrade*FinalWeight; } public double getUsualGrade() { return UsualGrade; } public void setUsualGrade(double usualGrade) { UsualGrade = usualGrade; } public double getFinalGrade() { return FinalGrade; } public void setFinalGrade(double finalGrade) { FinalGrade = finalGrade; } public double getUsualWeight() { return UsualWeight; } public void setUsualWeight(double usualWeight) { UsualWeight = usualWeight; } public double getFinalWeight() { return FinalWeight; } public void setFinalWeight(double finalWeight) { FinalWeight = finalWeight; } } class NoExamGrade extends Grade{ int FinalGrade; public double getTotalGrade(){ return FinalGrade; } public double getFinalGrade() { return FinalGrade; } public void setFinalGrade(int finalGrade) { FinalGrade = finalGrade; } } class WeightedGrade extends Grade { private ArrayList<Double> weightList = new ArrayList<Double>(); private ArrayList<Double> gradeList = new ArrayList<Double>(); int FinalGrade; public void setWeightList(ArrayList<Double> weightList) { this.weightList = weightList; } public double getTotalGrade() { double totalGrade = 0; for (int i = 0; i < weightList.size(); i++) { totalGrade += weightList.get(i) * gradeList.get(i); } return totalGrade; } public void setGradeList(ArrayList<Double> gradeList) { this.gradeList = gradeList; } public ArrayList<Double> getWeightList() { return weightList; } public ArrayList<Double> getGradeList() { return gradeList; } public double getFinalGrade() { return FinalGrade; } public void setFinalGrade(double sumScore) { FinalGrade = (int)sumScore; } public void setScoreList(ArrayList<Double> scoreList) { this.gradeList = scoreList; } } class Course{ String name; String kind; String method; ArrayList<Double> weightList = new ArrayList<Double>(); public Course(String name, String kind, String method) { this.name = name; this.kind = kind; this.method = method; } public String getName() { return name; } public String getMethod() { return method; } public String getKind() { return kind; } public ArrayList<Double> getWeightList() { return weightList; } public void setWeightList(List<Double> weightList) { this.weightList = (ArrayList<Double>) weightList; } } class Student{ String num; String name; public Student(String num, String name) { this.num = num; this.name = name; } public String getNum() { return num; } public String getName() { return name; } } class SelectCourse{ Course course; Student student; Grade grade; public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } }
分析:
-
main
方法:程序的入口点。它创建一个Scanner
对象来读取标准输入,并使用ParseInput
类的实例handle
处理输入。然后,它通过循环读取输入,直到输入为 "end"。在每次循环中,它调用handle.parseInput
方法来解析输入。 -
ParseInput
类:这个类包含了处理输入的方法。它维护了一些集合和映射来存储学生、课程和选课信息。它的parseInput
方法根据输入的格式解析输入,并根据解析结果执行相应的操作。主要功能是根据输入的格式,创建和管理学生、课程、选课以及成绩等相关信息。具体来说,它有以下几个重要的方法:
parseInput
方法:对输入进行解析和处理。根据输入的不同格式,进行相应的操作,如创建新课程、添加学生、选课等。checkCourse
、checkStudent
、checkClass
、checkSelect
方法:用于检查课程、学生、班级、选课的重复和存在性。studentScore
、CourseScore
、ClassScore
方法:分别计算并输出学生的平均分、课程的平均分和班级的平均分。MySort
方法:对学生、课程和选课记录进行排序。
-
InputMatching
类:这个类用于匹配输入的格式。它包含了一些正则表达式来匹配课程和成绩输入的格式。 -
Grade
抽象类:这是一个表示成绩的抽象类,定义了一个getTotalGrade
方法。Grade
及其子类用于表示不同类型的成绩。Grade
是一个抽象类,定义了获取总成绩的抽象方法。ExamGrade
、WeightedGrade
和NoExamGrade
是具体的子类,分别表示考试成绩、加权成绩和无考试成绩,并实现了计算总成绩的方法。 -
ExamGrade
类:这个类继承自Grade
类,表示考试成绩。它具有考试成绩和对应权重的属性,并通过重写getTotalGrade
方法来计算总成绩。
代码的主要流程是:读取输入 -> 解析输入 -> 执行相应的操作(创建课程、添加学生、录入成绩等) -> 最后按要求输出学生、课程和班级的成绩统计信息。
类图
难度分析图
家人们谁懂就过了样例
(3)采坑心得:
我觉得使我的课程成绩统计程序-1了,因为我在写第二次作业的时候我就发现了很大的问题。就比如说
这一部分,太不好改了,我如果要改就要这样,就是每个都要加一个实验的比较,再输入输出处理方面太麻烦了
尤其是在这一块,我是这么改的,我感觉逻辑上没问题呀,但是输出就是不对,
而且十分复杂以至于我加了300多行代码还不对,所以我觉得在写代码之前,一定要好好想想有没有什么其他更好的思路和逻辑,细细分析。
其他就是在定义`HashMap`或`LinkedHashMap`时,可以使用泛型来指定键和值的类型。这样可以在编译时进行类型检查,避免在运行时发生类型错误。
使用`Map`接口作为变量类型:在声明变量时,可以使用`Map`接口作为类型,而不是具体的实现类。这样可以使代码更加灵活,方便后续替换不同的`Map`实现。
代码中存在一些可能引发空指针异常的地方,例如在 parseInput
方法中检查课程是否存在时,未对返回的课程对象进行空判断。如果课程不存在,会导致空指针异常。
在处理学生的成绩输入时,代码对输入的长度进行了检查,但可能存在数组越界异常。例如,当输入的长度小于等于4时,访问 inputs[4]
会导致数组越界。
我觉得还有就是类之间的职责划分,第二次代码中的 ParseInput
类承担了过多的责任,包括解析输入、存储数据、处理成绩计算等。这导致这个类的职责不够清晰,可读性和可维护性较差。应该考虑将功能进行更细粒度的拆分,每个类专注于单一的职责。
(4)改进建议:
所以我觉得要改进的地方就是使用接口类型而非具体实现类:在声明变量时,应该使用接口类型作为变量类型,而不是具体的实现类。例如,`ArrayList<SelectCourse>`可以改为`List<SelectCourse>`,`HashMap<String, String>`可以改为`Map<String, String>`。这样可以增加代码的灵活性,方便后续替换不同的集合实现类。而且要用合适的集合类,在代码中使用了多个集合类来存储不同的对象。可以根据实际需求考虑使用不同的集合类,以提高代码的效率和可读性。例如,可以使用`HashSet`来存储不重复的班级名称,使用`LinkedHashMap`来保持插入顺序。
我写的代码部分代码逻辑较长,可以将其提取为独立的方法,以提高代码的可读性和可维护性。例如,parseInput
方法中的输入判断部分可以提取为独立的方法。可以尝试一下更高级的数据结构和算法:代码中使用了多个列表和哈希表,但在某些情况下可能存在效率和可读性方面的改进空间。可以考虑使用更高级的数据结构和算法,例如使用集合类来存储学生、课程和班级等信息,并使用流式操作或其他高级操作来简化和优化代码。
好好使用研究异常处理,在代码中未对可能发生的异常情况进行处理。建议添加适当的异常处理机制,例如使用 try-catch
块捕获异常,并给出相应的错误提示。
(5)总结:
通过编写这个学生成绩系类,我学会了如何使用Java编程语言来构建一个基本的命令行应用程序,了解了面向对象编程的基本概念和原则,并将其应用到了项目中。
学习了类的定义和使用,对象的创建和操作,以及如何设计和组织代码结构。掌握了异常处理的方法和技巧,以及如何在程序中有效地处理错误和异常情况。
更加了解并使用集合类(如ArrayList和HashMap)来存储和管理数据,并应用它们来实现系统的各项功能。通过自己的思考和查阅相关资料,我成功地解决了一些问题并提高了对Java编程的理解能力。一步一步逐渐完善自己设计,这是个艰辛但成果很愉悦的过程。还有就是编程思维得到了训练和提升,掌握了一些基础题目的编
思想。了解了开闭原则,及继承和多态的使用,对面向对象又有了一层新的认识。在写PTA的过程中我意识到自己代码的可读性十分差,条理性还不够清晰,我应
注重代码书写习惯。所以学习JAVA,不仅对我们以后学习其他语言有很大的好处,而且也让我们知道了和理解了作为一个编程人员首先应具有的良好心理素质,那
是冷静思考和专心致志。对待学术知识应该是严谨和认真。
还是路漫漫其修远兮。
标签:inputs,return,String,int,Blog,course,public From: https://www.cnblogs.com/xxx10171125/p/17499344.html