1.第三阶段PTA题目集总结
(1)前言:第三阶段的题目集算是对所有已学知识的综合运用,另外还有对容器map、set、list以及栈的考察运用。这意味着对知识的理解运用变得更难,不再是单纯对给出类图的简单“翻译”,更需要靠自己去思考怎么去构建一个符合面向对象原则的程序。尤其是三次课程成绩统计程序的迭代,不仅是java语法的综合运用,还需要一个正确的思维逻辑,否则写起来会非常混乱。第三阶段的题量不大,好几次作业就一道题,但是那一道题就要头疼个好几天,真的很难很有挑战性。
(2)设计与分析:
1.课程成绩统计程序1.0
个人觉得这个程序非常头疼的一点在于需要分析到底什么时候输出什么,哪些情况输出什么,有些限制条件需要分析题给的输入输出样例才能看出来。
我写这道题的过程是先审题把需要的最底层的类写好,根据题给参考类图依次写好学生类,班级类,课程类,成绩类,考试成绩类考察成绩类以及选课类:
不急着写Main类,对于这种题目冗长的需要先分析清楚。先分别详细分析输入和输出,输入包括课程信息和课程成绩,输出包括三个,学生课程成绩、单门课程成绩、班级所有课程总成绩。
输入
课程信息:需要两个正则表达式
课程名称 + 课程性质
【1-10的汉字或字母 + 必修】
课程名称 + 课程性质 + 考核方式
【1-10的汉字或字母 + 必修 + 考试】
【1-10的汉字或字母 + 选修 + 考察】
【1-10的汉字或字母 + 选修 + 考试】
以上是正常的情况,异常情况的处理如下
(1)课程信息重复:需要创建课程列表,若首次输入该课程就加入,课程列表中有该课程就不加入
(2)输入课程性质与考核方式不匹配(例如 必修+考察):输出-课程名称+" : course type & access mode mismatch"
成绩信息:需要两个正则表达式
学号 + 姓名 + 课程名称 + 期末成绩
【8位的数字 + 1-10位的汉字 + 1-10的汉字或字母(考察) + 1-100的数字】
学号 姓名 课程名称 平时成绩 期末成绩
【8位的数字 + 1-10位的汉字 + 1-10的汉字或字母 + 1-100的数字 + 1-100的数字】
以上是正常的情况,异常情况的处理如下:
(1)课程名称不在课程列表中:输出-学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"
(2)输入的成绩数量与课程的考核方式不匹配(属于第一种输入情况但是课程考核方式是考试):输出-课程名称+" : course type & access mode mismatch"
我创建了三个hashMap用来储存已输入的课程、学生、班级(因为输出需要判断是否有成绩信息),以及一个hashSet用来储存已输入的正确的选课信息。设计了一个循环判断输入的一行是否符合以上的正确情况,若符合就进行相关的数据读入,不符合就输出wrong format,并输入下一行,以“end”作为循环结束标志。
输出
(1)学生课程总成绩平均分:计算一个学生所有的课程成绩的平均分,存进TreeMap<学号,平均分>,如果没有成绩信息则平均分为-1,输出时利用TreeMap排序按学号由低到高排序。
平均分为-1输出 学号+英文空格+姓名+英文空格+"did not take any exams"
正常输出 学号+英文空格+姓名+英文空格+总成绩平均分
(2)单门课程成绩平均分:计算一门课程所有总成绩的平均分,以及所有平时成绩的平均分,以及所有期末考试平均分,存进三个TreeMap<课程名称,平均分>,其它同上
期末考试平均分为-1输出 课程名称+英文空格+"has no grades yet"
平时考试平均分为-1且期末不为-1 课程名称+英文空格+期末考试平均分+英文空格+总成绩平均分
正常输出 课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分
(3)班级所有课程总成绩平均分:要先计算班级内每一个学生的课程总成绩平均分,然后再计算班级所有学生的平均分的平均分,存进TreeMap<班级号,平均分>,其它同上
平均分为-1输出 班级名称+英文空格+ "has no grades yet"
正常输出 班级号+英文空格+总成绩平均分
至此算是分析完了,我是先分析完后再像填空一样补上了main类,以下是完整代码:
package Grade; import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String word = input.nextLine(); HashMap<String, Course> courses = new HashMap<>();//课程列表 HashMap<String, Student> students = new HashMap<>();//学生列表 HashMap<String, Class> classes = new HashMap<>();//班级列表 HashSet<CourseSelection> courseSelections = new HashSet<>();//选课列表 //输入 while(!word.equals("end")){ boolean flag = true;//判断是否格式错误的标志 String course1 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}"; String course2 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}\\s[一-龥]{2}"; String score1 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}\\s[1-9]\\d+?$|100$|0$"; String score2 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}\\s[1-9]\\d+?$|100$|0$\\s[1-9]\\d+?$|100$|0$"; if(word.matches(course1)){//课程名称 课程性质 String[] words = word.split(" "); if(!courses.containsKey(words[0])){//如果列表中没有该课程 courses.put(words[0], new Course(words[0], words[1], "考试")); } } else if (word.matches(course2)) {//课程名称 课程性质 考核方式 String[] words = word.split(" "); if(words[1].equals("必修") && words[2].equals("考察")){ System.out.println(words[0] + " : course type & access mode mismatch"); }else if (!courses.containsKey(words[0])){ courses.put(words[0], new Course(words[0], words[1], words[2])); } } else if (word.matches(score1)) {//学号 姓名 课程名称 期末成绩 String[] words = word.split(" "); Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ System.out.println(words[2] + " does not exist"); }else{ if(courses.get(words[2]).assessmentMethod.equals("考试")){ System.out.println(words[0] + " " + words[1] + " : access mode mismatch"); }else{ Score score = new ExamineScore(Integer.parseInt(words[3])); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } else if (word.matches(score2)) {//学号 姓名 课程名称 平时成绩 期末成绩 String[] words = word.split(" "); Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ System.out.println(words[0] + " " + words[1] + " :" + words[2] + " does not exist"); }else{ Score score; if(courses.get(words[2]).assessmentMethod.equals("考试")){ score = new ExamScore(Integer.parseInt(words[3]), Integer.parseInt(words[4])); }else { score = new ExamineScore(Integer.parseInt(words[3]), Integer.parseInt(words[4])); } courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } }else{ flag = false; } word = input.nextLine(); if(!flag){ System.out.println("wrong format"); } } printStudentScore(students, courseSelections); printCourseScore(courses, courseSelections); printClassScore(classes, courseSelections); } public static void printStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> studentScore = new TreeMap<>();//所有学生课程总成绩平均分 getStudentScore(students, courseSelections, studentScore); for (String s : studentScore.keySet()) { if(studentScore.get(s) == -1){ System.out.println(s + " " + students.get(s).name + " did not take any exams"); }else { System.out.println(s + " " + students.get(s).name + " " + studentScore.get(s)); } } } public static void getStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> studentScore){ for (String s : students.keySet()) { int m = 0, n = 0; boolean flag = false;//有成绩信息的标志 for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.student.ID)){ m = m + courseSelection.score.getScore(); n++; flag = true; } } if(flag){ studentScore.put(s, m/n); }else { studentScore.put(s, -1); } } } public static void printCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> courseScore = new TreeMap<>();//所有课程总成绩平均分 TreeMap<String, Integer> usualScore = new TreeMap<>();//平时成绩平均分 TreeMap<String, Integer> finalScore = new TreeMap<>();//期末成绩平均分 getCourseScore(courses, courseSelections, courseScore,1); getCourseScore(courses, courseSelections, usualScore,2); getCourseScore(courses, courseSelections, finalScore,3); for (String s : courseScore.keySet()) { if(finalScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else { if(usualScore.get(s) == -1){ System.out.println(s + " " + finalScore.get(s) + " " + courseScore.get(s)); }else { System.out.println(s + " " + usualScore.get(s) + " " + finalScore.get(s) + " " + courseScore.get(s)); } } } } public static void getCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> score, int i){ for (String s : courses.keySet()) { int m = 0, n = 0; boolean flag = false; for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.course.name)){ if(i == 1){ m = m + courseSelection.score.getScore(); flag = true; } else if (i == 2) { m = m + courseSelection.score.getUsualScore(); if(courseSelection.score.getUsualScore() != -1){ flag = true; } } else { m = m + courseSelection.score.getFinalScore(); flag = true; } n++; } } if(flag){ score.put(s, m/n); }else { score.put(s, -1); } } } public static void printClassScore(HashMap<String, Class> classes, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> classScore = new TreeMap<>();//所有班级所有课程总成绩平均分 for (String s : classes.keySet()) { TreeMap<String, Integer> studentScore = new TreeMap<>();//一个班所有学生的成绩 getStudentScore(classes.get(s).students, courseSelections, studentScore); int m = 0, n = 0; boolean flag = false; for (String s1 : studentScore.keySet()) { if(studentScore.get(s1) != -1){ m = m + studentScore.get(s1); n++; flag = true; } } if(flag){ classScore.put(s, m/n); }else{ classScore.put(s, -1); } } for (String s : classScore.keySet()) { if(classScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else{ System.out.println(s + " " + classScore.get(s)); } } } }
package Grade; public class Student { String ID = "";//学号 String name = "";//姓名 public Student() { } public Student(String ID, String name) { this.ID = ID; this.name = name; } }
package Grade; import java.util.HashMap; public class Class { String classID = ""; HashMap<String,Student> students = new HashMap<>(); public Class() { } public Class(String classID, Student student) { this.classID = classID; this.students.put(student.ID, student); } }
package Grade; public class Course { String name;//课程名称 String type;//课程性质 String assessmentMethod;//考核方式 public Course() { } public Course(String name, String type, String assessmentMethod) { this.name = name; this.type = type; this.assessmentMethod = assessmentMethod; } }
public abstract class Score { int usualScore = -1;//平时成绩 int finalScore = -1;//期末成绩 public Score() { } public int getUsualScore() { return usualScore; } public int getFinalScore() { return finalScore; } public Score(int finalScore) { this.finalScore = finalScore; } public Score(int usualScore, int finalScore) { this.usualScore = usualScore; this.finalScore = finalScore; } public abstract int getScore(); }
package Grade; public class ExamScore extends Score { @Override public int getScore() { return (int)(usualScore * 0.3 + finalScore * 0.7); } public ExamScore() { } public ExamScore(int usualScore, int finalScore) { super(usualScore, finalScore); } }
package Grade; public class ExamineScore extends Score { @Override public int getScore() { return finalScore; } public ExamineScore() { } public ExamineScore(int usualScore, int finalScore) { super(usualScore, finalScore); } public ExamineScore(int finalScore) { super(finalScore); } }
package Grade; public class CourseSelection { Course course = new Course(); Student student = new Student(); Score score; public CourseSelection() { } public CourseSelection(Course course, Student student, Score score) { this.course = course; this.student = student; this.score = score; } }
这不是我最开始写的代码,最开始的那一版由于没有用map和set,导致代码非常冗长,超出了pta的代码长度限制,没法提交,最后即便提交了也是因为中途删改不知道删掉了什么重要的部分导致编译错误,所以迭代2作业发布的时候我重新写了一遍,只保证了给出的样例输入输出是正确的,依然有逻辑上的bug。
2.课程成绩统计程序2.0
迭代2在1.0的基础上增加了实验课,这意味着情况变得更加复杂,写的时候脑子都要炸了。增加了一个ExperimentalScore类:
和1.0一样先进行分析,大体情况和第一版是一样的,新增了几种情况,但不需要改动太多地方,重复的地方不再赘述
输入
课程信息新增情况:
课程名称 + 课程性质 + 考核方式
【1-10的汉字或字母 + 实验 + 实验】
成绩信息:需要三个正则表达式
学号 + 姓名 + 课程名称 + 期末成绩
【8位的数字 + 1-10位的汉字 + 1-10的汉字或字母(考核方式非考试且非实验) + 1-100的数字】
学号 + 姓名 + 课程名称 + 平时成绩 + 期末成绩
【8位的数字 + 1-10位的汉字 + 1-10的汉字或字母(考核方式非实验) + 1-100的数字 + 1-100的数字】
学号 + 姓名 + 课程名称 + 实验次数 + 实验成绩......
【8位的数字 + 1-10位的汉字 + 1-10的汉字或字母 + 4-9的数字 + 1-100的数字(三次及以上)】
以上是正常的情况,新增对实验成绩的异常情况处理如下:
输入的实验成绩数量与输入的实验次数不相等:学号+英文空格+姓名+英文空格+": access mode mismatch"
输出
对单门课程成绩平均分的输出做了修改:(直接上图)
以下是新增的实验成绩类和修改的Main类
package t1003; public class experimentalScore extends Score{ int[] score; @Override public int getScore() { int total = 0; for (int i : score) { total = total + i; } return total/score.length; } public experimentalScore() { } public experimentalScore(int[] score) { this.score = score; } }
package t1003; import java.util.HashMap; import java.util.HashSet; import java.util.Scanner; import java.util.TreeMap; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String word = input.nextLine(); HashMap<String, Course> courses = new HashMap<>();//课程列表 HashMap<String, Student> students = new HashMap<>();//学生列表 HashMap<String, Class> classes = new HashMap<>();//班级列表 HashSet<CourseSelection> courseSelections = new HashSet<>();//选课列表 HashSet<HashMap<Integer, String[]>> wrongInformation = new HashSet<>();//所有的错误信息 //输入 while(!word.equals("end")){ HashMap<Integer, String[]> wrong = new HashMap<>();//储存错误信息 String course1 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}"; String course2 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}\\s[一-龥]{2}"; String score1 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}\\s\\d{1,3}"; String score2 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}(\\s\\d{1,3}){2}"; String score3 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}\\s[4-9](\\s\\d{1,3}){3,}"; if(word.matches(course1)){//课程名称 课程性质 String[] words = word.split(" "); if(!courses.containsKey(words[0])){//如果列表中没有该课程 courses.put(words[0], new Course(words[0], words[1], "考试")); } } else if (word.matches(course2)) {//课程名称 课程性质 考核方式 String[] words = word.split(" "); if((words[1].equals("必修") && words[2].equals("考察")) || (words[1].equals("实验") && !words[2].equals("实验")) || (!words[1].equals("实验") && words[2].equals("实验"))){ String[] wrongWord = {words[0]}; wrong.put(3, wrongWord); }else if (!courses.containsKey(words[0])){ courses.put(words[0], new Course(words[0], words[1], words[2])); } } else if (word.matches(score1)) {//学号 姓名 课程名称 期末成绩 String[] words = word.split(" "); if(Integer.parseInt(words[3]) > 100){ String[] wordWord = {"wrong format"}; wrong.put(4, wordWord); }else { Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else{ if(courses.get(words[2]).assessmentMethod.equals("考试") || courses.get(words[2]).assessmentMethod.equals("实验")){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else{ Score score = new ExamineScore(Integer.parseInt(words[3])); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else if (word.matches(score2)) {//学号 姓名 课程名称 平时成绩 期末成绩 String[] words = word.split(" "); if(Integer.parseInt(words[3]) > 100 || Integer.parseInt(words[4]) > 100){ String[] wordWord = {"wrong format"}; wrong.put(4, wordWord); }else { Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else{ if(courses.get(words[2]).assessmentMethod.equals("实验")){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else { Score score; if(courses.get(words[2]).assessmentMethod.equals("考试")){ score = new ExamScore(Integer.parseInt(words[3]), Integer.parseInt(words[4])); }else { score = new ExamineScore(Integer.parseInt(words[3]), Integer.parseInt(words[4])); } courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else if (word.matches(score3)) {//学号 姓名 课程名称 实验次数 实验成绩... String[] words = word.split(" "); boolean flag = false; for (int i = 4; i < words.length; i++) { if(Integer.parseInt(words[i]) > 100){ flag = true; } } if(flag){ String[] wordWord = {"wrong format"}; wrong.put(4, wordWord); }else { Student student = new Student(words[0],words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else { if(Integer.parseInt(words[3]) != words.length - 4){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else{ int[] scores = new int[Integer.parseInt(words[3])]; for (int i = 0; i < Integer.parseInt(words[3]); i++) { scores[i] = Integer.parseInt(words[4 + i]); } Score score = new experimentalScore(scores); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else{ String[] wordWord = {"wrong format"}; wrong.put(4, wordWord); } wrongInformation.add(wrong); word = input.nextLine(); } for (HashMap<Integer, String[]> wrong : wrongInformation) { for (Integer i : wrong.keySet()) { if(i == 1){ String[] words = wrong.get(i); System.out.println(words[0] + " " + words[1] + " :" + words[2] + " does not exist"); }else if (i == 2){ String[] words = wrong.get(i); System.out.println(words[0] + " " + words[1] + " : access mode mismatch"); }else if (i == 3){ String[] words = wrong.get(i); System.out.println(words[0] + " : course type & access mode mismatch"); }else { System.out.println(wrong.get(i)[0]); } } } printStudentScore(students, courseSelections); printCourseScore(courses, courseSelections); printClassScore(classes, courseSelections); } public static void printStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> studentScore = new TreeMap<>();//所有学生课程总成绩平均分 getStudentScore(students, courseSelections, studentScore); for (String s : studentScore.keySet()) { if(studentScore.get(s) == -1){ System.out.println(s + " " + students.get(s).name + " did not take any exams"); }else { System.out.println(s + " " + students.get(s).name + " " + studentScore.get(s)); } } } public static void getStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> studentScore){ for (String s : students.keySet()) { int m = 0, n = 0; boolean flag = false;//有成绩信息的标志 for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.student.ID)){ m = m + courseSelection.score.getScore(); n++; flag = true; } } if(flag){ studentScore.put(s, m/n); }else { studentScore.put(s, -1); } } } public static void printCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> courseScore = new TreeMap<>();//所有课程总成绩平均分 TreeMap<String, Integer> usualScore = new TreeMap<>();//平时成绩平均分 TreeMap<String, Integer> finalScore = new TreeMap<>();//期末成绩平均分 getCourseScore(courses, courseSelections, courseScore,1); getCourseScore(courses, courseSelections, usualScore,2); getCourseScore(courses, courseSelections, finalScore,3); for (String s : courseScore.keySet()) { if(courseScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else { if(usualScore.get(s) == -1){ if(finalScore.get(s) == -1){ System.out.println(s + " " + courseScore.get(s)); }else { System.out.println(s + " " + finalScore.get(s) + " " + courseScore.get(s)); } }else { System.out.println(s + " " + usualScore.get(s) + " " + finalScore.get(s) + " " + courseScore.get(s)); } } } } public static void getCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> score, int i){ for (String s : courses.keySet()) { int m = 0, n = 0; boolean flag = false; for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.course.name)){ if(i == 1){ m = m + courseSelection.score.getScore(); flag = true; } else if (i == 2) { m = m + courseSelection.score.getUsualScore(); if(courseSelection.score.getUsualScore() != -1){ flag = true; } } else { m = m + courseSelection.score.getFinalScore(); if(courseSelection.score.getFinalScore() != -1){ flag = true; } } n++; } } if(flag){ score.put(s, m/n); }else { score.put(s, -1); } } } public static void printClassScore(HashMap<String, Class> classes, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> classScore = new TreeMap<>();//所有班级所有课程总成绩平均分 for (String s : classes.keySet()) { TreeMap<String, Integer> studentScore = new TreeMap<>();//一个班所有学生的成绩 getStudentScore(classes.get(s).students, courseSelections, studentScore); int m = 0, n = 0; boolean flag = false; for (String s1 : studentScore.keySet()) { if(studentScore.get(s1) != -1){ m = m + studentScore.get(s1); n++; flag = true; } } if(flag){ classScore.put(s, m/n); }else{ classScore.put(s, -1); } } for (String s : classScore.keySet()) { if(classScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else{ System.out.println(s + " " + classScore.get(s)); } } } }
这一次作业修改了第一版的逻辑bug,到最后离满分只差四分,只有一个测试点没通过,实在找不到是哪个了,具体的调试修改过程会在踩坑心得里详述。
3.课程成绩统计程序3.0
实在是写不来了。
3.0对2.0的计算总成绩的方法进行了修改,修改了类结构,课程信息的输入也修改了,变成了权重计算法。先按题目要求将成绩类的继承关系改成组合关系,修改后的类图如下:
然后同样的,遇到复杂问题先分析:
输入
课程信息:需要四个正则表达式,以下是新增情况:
课程名称 + 课程性质 + 考核方式 + 平时成绩的权重 + 期末成绩的权重
【1-10的汉字和字母 + 必修 + 考试 + 小数 + 小数】
【1-10的汉字和字母 + 选修 + 考试 + 小数 + 小数】
课程名称 + 课程性质 + 考核方式 + 成绩数量 + 权重...
【1-10的汉字和字母 + 实验 + 实验 + 4-9的数字 + 小数 ...】
新增异常处理:
(1)所有权重相加不等于1:输出-课程名称+" : weight value error"
(2)分项成绩数量和分项成绩权重个数不相同:输出-课程名称+" : number of scores does not match"
成绩信息:需要三个正则表达式,以下是新增情况:
学号 + 姓名 + 课程名称 + 成绩...
【8位的数字 + 1-10的汉字 + 1-10的汉字和字母 + 1-100的数字...(大于等于3次)】
输出
对于学生成绩和班级成绩的输出没什么改变,课程成绩的输出更简单了,只要输出课程的总成绩就行
这次的程序写得并不好,有一大串的测试点没过(我猜是有一个共同的地方出了问题),在写代码的时候我并没有把这些情况捋清楚,在刚才写分析的过程中发现了代码中的逻辑bug,之后我还要进行修改,以下是我暂时有问题的全部代码:
package t1102; import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String word = input.nextLine(); HashMap<String, Course> courses = new HashMap<>();//课程列表 HashMap<String, Student> students = new HashMap<>();//学生列表 HashMap<String, Class> classes = new HashMap<>();//班级列表 HashSet<CourseSelection> courseSelections = new HashSet<>();//选课列表 HashSet<HashMap<Integer, String[]>> wrongInformation = new HashSet<>();//所有的错误信息 //输入 while(!word.equals("end")){ HashMap<Integer, String[]> wrong = new HashMap<>();//储存错误信息 String course1 = "[一-龥a-zA-Z]{1,10}\\s必修"; String course2 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}\\s[一-龥]{2}"; String course3 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}\\s[一-龥]{2}(\\s\\d+\\.\\d+){2}"; String course4 = "[一-龥a-zA-Z]{1,10}\\s[一-龥]{2}\\s[一-龥]{2}\\s[4-9](\\s\\d+\\.\\d+)*"; String score1 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}\\s\\d{1,3}"; String score2 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}(\\s\\d{1,3}){2}"; String score3 = "[0-9]{8}\\s[一-龥]{1,10}\\s[一-龥a-zA-Z]{1,10}(\\s\\d{1,3}){4,9}"; if(word.matches(course1)){ String[] words = word.split(" "); if(!courses.containsKey(words[0])){//如果列表中没有该课程 courses.put(words[0], new Course(words[0], words[1], "考试", new ArrayList<>())); } }else if(word.matches(course2)){//课程名称 课程性质 考核方式 String[] words = word.split(" "); if((words[1].equals("必修") && words[2].equals("考察")) || (words[1].equals("实验") && !words[2].equals("实验")) || (!words[1].equals("实验") && words[2].equals("实验"))){ String[] wrongWord = {words[0]}; wrong.put(3, wrongWord); }else if (!courses.containsKey(words[0])){ ArrayList<Double> weight = new ArrayList<>(); weight.add(1.0); courses.put(words[0], new Course(words[0], words[1], words[2], weight)); } } else if (word.matches(course3)) {//课程名称 课程性质 考核方式 平时成绩的权重 期末成绩的权重 String[] words = word.split(" "); if((words[1].equals("必修") && words[2].equals("考察")) || (words[1].equals("实验") && !words[2].equals("实验")) || (!words[1].equals("实验") && words[2].equals("实验"))){ String[] wrongWord = {words[0]}; wrong.put(3, wrongWord); }else if(Double.parseDouble(words[3]) + Double.parseDouble(words[4]) != 1){ String[] wrongWord = {words[0]}; wrong.put(4, wrongWord); } else if (!courses.containsKey(words[0])) { ArrayList<Double> weight = new ArrayList<>(); weight.add(Double.parseDouble(words[3])); weight.add(Double.parseDouble(words[4])); courses.put(words[0], new Course(words[0], words[1], words[2], weight)); } } else if (word.matches(course4)) {//课程名称 课程性质 考核方式 成绩数量 权重... String[] words = word.split(" "); double totalWeight = 0; for (int i = 4; i < words.length; i++) { totalWeight = totalWeight + Double.parseDouble(words[i]); } if((words[1].equals("必修") && words[2].equals("考察")) || (words[1].equals("实验") && !words[2].equals("实验")) || (!words[1].equals("实验") && words[2].equals("实验"))){ String[] wrongWord = {words[0]}; wrong.put(3, wrongWord); }else if(words.length - 4 != Integer.parseInt(words[3])){ String[] wrongWord = {words[0]}; wrong.put(5, wrongWord); } else if (totalWeight != 1) { String[] wrongWord = {words[0]}; wrong.put(4, wrongWord); }else if(!courses.containsKey(words[0])){ ArrayList<Double> weight = new ArrayList<>(); for (int i = 4; i < words.length; i++) { weight.add(Double.parseDouble(words[i])); } courses.put(words[0], new Course(words[0], words[1], words[2], weight)); } } else if (word.matches(score1)) {//学号 姓名 课程名称 期末成绩 String[] words = word.split(" "); if(Integer.parseInt(words[3]) > 100){ String[] wordWord = {"wrong format"}; wrong.put(6, wordWord); }else { Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else{ if(courses.get(words[2]).assessmentMethod.equals("考试") || courses.get(words[2]).assessmentMethod.equals("实验")){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else{ ArrayList<ItemizedScore> itemizedScores = new ArrayList<>(); itemizedScores.add(new ItemizedScore(Integer.parseInt(words[3]), 1)); Score score = new Score(itemizedScores); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else if (word.matches(score2)) {//学号 姓名 课程名称 平时成绩 期末成绩 String[] words = word.split(" "); if(Integer.parseInt(words[3]) > 100 || Integer.parseInt(words[4]) > 100){ String[] wordWord = {"wrong format"}; wrong.put(6, wordWord); }else { Student student = new Student(words[0], words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else{ if(courses.get(words[2]).assessmentMethod.equals("实验") || courses.get(words[2]).assessmentMethod.equals("考察")){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else { ArrayList<ItemizedScore> itemizedScores = new ArrayList<>(); itemizedScores.add(new ItemizedScore(Integer.parseInt(words[3]), courses.get(words[2]).weight.get(0))); itemizedScores.add(new ItemizedScore(Integer.parseInt(words[4]), courses.get(words[2]).weight.get(1))); Score score = new Score(itemizedScores); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else if (word.matches(score3)) {//学号 姓名 课程名称 成绩... String[] words = word.split(" "); boolean flag = false; for (int i = 4; i < words.length; i++) { if(Integer.parseInt(words[i]) > 100){ flag = true; } } if(flag){ String[] wordWord = {"wrong format"}; wrong.put(6, wordWord); }else { Student student = new Student(words[0],words[1]); if(!courses.containsKey(words[2])){ String[] wrongWord = {words[0], words[1], words[2]}; wrong.put(1, wrongWord); }else { if(courses.get(words[2]).weight.size() != words.length - 3){ String[] wrongWord = {words[0], words[1]}; wrong.put(2, wrongWord); }else{ ArrayList<ItemizedScore> itemizedScores = new ArrayList<>(); for (int i = 3; i < words.length; i++) { itemizedScores.add(new ItemizedScore(Integer.parseInt(words[i]), courses.get(words[2]).weight.get(i - 3))); } Score score = new Score(itemizedScores); courseSelections.add(new CourseSelection(courses.get(words[2]), student, score)); } } if(!students.containsKey(words[0])){ students.put(words[0], student); } if(classes.containsKey(words[0].substring(0,6))){ classes.get(words[0].substring(0,6)).students.put(words[0], student); }else { classes.put(words[0].substring(0,6), new Class(words[0].substring(0,6), student)); } } } else{ String[] wordWord = {"wrong format"}; wrong.put(6, wordWord); } wrongInformation.add(wrong); word = input.nextLine(); } for (HashMap<Integer, String[]> wrong : wrongInformation) { for (Integer i : wrong.keySet()) { if(i == 1){ String[] words = wrong.get(i); System.out.println(words[0] + " " + words[1] + " :" + words[2] + " does not exist"); }else if (i == 2){ String[] words = wrong.get(i); System.out.println(words[0] + " " + words[1] + " : access mode mismatch"); }else if (i == 3){ String[] words = wrong.get(i); System.out.println(words[0] + " : course type & access mode mismatch"); } else if (i == 4) { String[] words = wrong.get(i); System.out.println(words[0] + " : weight value error"); } else if (i == 5) { String[] words = wrong.get(i); System.out.println(words[0] + " : number of scores does not match"); } else { System.out.println(wrong.get(i)[0]); } } } printStudentScore(students, courseSelections); printCourseScore(courses, courseSelections); printClassScore(classes, courseSelections); } public static void printStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> studentScore = new TreeMap<>();//所有学生课程总成绩平均分 getStudentScore(students, courseSelections, studentScore); for (String s : studentScore.keySet()) { if(studentScore.get(s) == -1){ System.out.println(s + " " + students.get(s).name + " did not take any exams"); }else { System.out.println(s + " " + students.get(s).name + " " + studentScore.get(s)); } } } public static void getStudentScore(HashMap<String, Student> students, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> studentScore){ for (String s : students.keySet()) { int m = 0, n = 0; boolean flag = false;//有成绩信息的标志 for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.student.ID)){ m = m + courseSelection.score.getScore(); n++; flag = true; } } if(flag){ studentScore.put(s, m/n); }else { studentScore.put(s, -1); } } } public static void printCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> courseScore = new TreeMap<>();//所有课程总成绩平均分 getCourseScore(courses, courseSelections, courseScore); for (String s : courseScore.keySet()) { if(courseScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else { System.out.println(s + " " + courseScore.get(s)); } } } public static void getCourseScore(HashMap<String, Course> courses, HashSet<CourseSelection> courseSelections, TreeMap<String, Integer> score){ for (String s : courses.keySet()) { int m = 0, n = 0; boolean flag = false; for (CourseSelection courseSelection : courseSelections) { if(s.equals(courseSelection.course.name)){ m = m + courseSelection.score.getScore(); flag = true; n++; } } if(flag){ score.put(s, m/n); }else { score.put(s, -1); } } } public static void printClassScore(HashMap<String, Class> classes, HashSet<CourseSelection> courseSelections){ TreeMap<String, Integer> classScore = new TreeMap<>();//所有班级所有课程总成绩平均分 for (String s : classes.keySet()) { TreeMap<String, Integer> studentScore = new TreeMap<>();//一个班所有学生的成绩 getStudentScore(classes.get(s).students, courseSelections, studentScore); int m = 0, n = 0; boolean flag = false; for (String s1 : studentScore.keySet()) { if(studentScore.get(s1) != -1){ m = m + studentScore.get(s1); n++; flag = true; } } if(flag){ classScore.put(s, m/n); }else{ classScore.put(s, -1); } } for (String s : classScore.keySet()) { if(classScore.get(s) == -1){ System.out.println(s + " has no grades yet"); }else{ System.out.println(s + " " + classScore.get(s)); } }
package t1102; public class Student { String ID = "";//学号 String name = "";//姓名 public Student() { } public Student(String ID, String name) { this.ID = ID; this.name = name; } }
package t1102; import java.util.HashMap; public class Class { String classID = ""; HashMap<String, Student> students = new HashMap<>(); public Class() { } public Class(String classID, Student student) { this.classID = classID; this.students.put(student.ID, student); } }
package t1102; import java.util.ArrayList; public class Course { String name;//课程名称 String type;//课程性质 String assessmentMethod;//考核方式 ArrayList<Double> weight = new ArrayList<>();//权重 public Course() { } public Course(String name, String type, String assessmentMethod, ArrayList<Double> weight) { this.name = name; this.type = type; this.assessmentMethod = assessmentMethod; this.weight = weight; } }
package t1102; import java.util.ArrayList; public class Score { ArrayList<ItemizedScore> score = new ArrayList<>();//所有的分项成绩 public Score() { } public Score(ArrayList<ItemizedScore> score) { this.score = score; } public int getScore(){ double totalScore = 0; for (ItemizedScore itemizedScore : score) { totalScore = totalScore + itemizedScore.score * itemizedScore.weight; } return (int)totalScore; } }
package t1102; public class ItemizedScore { int score;//分值 double weight;//权重 public ItemizedScore() { } public ItemizedScore(double weight) { this.weight = weight; } public ItemizedScore(int score, double weight) { this.score = score; this.weight = weight; } }
package t1102; public class CourseSelection { Course course = new Course(); Student student = new Student(); Score score; public CourseSelection() { } public CourseSelection(Course course, Student student, Score score) { this.course = course; this.student = student; this.score = score; } }
(3)踩坑心得:我对于bug的测试修改主要实在写第二次迭代的时候,第二次在努力达到满分的同时也修改了第一次的bug,第三次的逻辑bug较多,暂时还没有捋清楚。所以以下分析一下我写2.0的踩坑过程
首先是正则表达式,我在菜单程序和这次的三次迭代中吃了正则表达式很大的亏,因为正则表达式写不出来,没办法精确的判断,导致我写代码的进度缓慢而且总是找不出bug,从1.0到2.0的改进最大的一个部分就是修改了用来读入数据的正则表达式,而且我认为我3.0出了问题估计也是正则表达式出错的原因。
然后做了一个很大的改动是添加了一个“储存错误信息”的HashSet,用来保证输出异常情况的顺序,但事实是通过的测试点数量并没有因此增加,我正在怀疑这个改动是否有必要......(如图是修改后的异常情况输出的部分代码)
让我的得分有了一个质的飞跃的是我修改了课程成绩输出的一个逻辑判断
得分只有8分时:
修改后直接48分:(其实可以更精简)
最后56分:
只能说在算法这方面实在是很难,牵一发而动全身,有时候离成功只差一点点。
(4)改进建议:
(5)总结:对本阶段(10-16周)综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。
2.本门课程总结
教学理念(OBE)、教学方法(边讲边练)、教学组织(线上线下混合式教学)、教学过程(PTA题目集驱动)及教学模式(BOPPPS)进行客观性评价,给出相应建议及意见,希望大家畅所欲言,重点查摆问题,多否定,少肯定