关于成绩统计程序类的结构理解(老师提供的结构代码)
这里以课程成绩统计程序-3为代表,本质上三个题目的差别度不大,核心思想都没用太大处。
尤其和前面的点菜系统有很强的相似性。
输入结构
课程 名字 性质 考核方式 权重的个数(1,2,4-9不等)
考试 两个成绩,两个权重
考察 一个成绩 一个权重
实验 多个实验成绩 多个权重
数据处理
成绩信息类 = 课程成绩类 + 分项成绩类
课程成绩类 = 分项成绩类 + 分项成绩类 + 分项成绩类 + …
分项成绩类 = 成绩权重 + 成绩分值
核心思想
- 学生
根据遍历每一遍记录表里面的学生姓名进行读取该学生的所有记录。
该记录里面有 学生类(name+ID) + 课程类(name,way,date) + 成绩类()。
必须得根据课程的分项权重对成绩类中的分项权重进行赋值,这样在Show_Student的时候可以直接用total进行存储。
(可以尝试在读入记录的同时对记录中的成绩权重进行赋值)
- 课程
根据遍历每一遍记录表里面的课程名字进行读取该课程选修学生的所有记录
该记录里面有 学生类(name+ID) + 课程类(name,way,date) + 成绩类()。
必须得根据课程的分项权重对成绩类中的分享项重进行赋值,这样在Show_Course的时候可以直接用total进行存储。
(可以尝试在读入记录的同时对记录中的成绩权重进行赋值)
- 班级
根据遍历每一遍记录表里面的学生ID进行读取该班级学生的所有记录。
该记录里面有 学生类(name+ID) + 课程类(name,way,date) + 成绩类()。.
必须得根据课程的分项权重对成绩类中的分享项重进行赋值,这样在Show_Classroom的时候可以直接用total进行存储。
(可以尝试在读入记录的同时对记录中的成绩权重进行赋值)
目录
- 面向对象程序设计A---第6次题目集:7-1 课程成绩统计程序-1
- 面向对象程序设计A---第7次题目集:7-3 课程成绩统计程序-2
- 面向对象程序设计A---第8次题目集:7-2 课程成绩统计程序-3
面向对象程序设计A---第6次题目集:7-1 课程成绩统计程序-1
难度
:****
PowerDesigner
SourceMonitor
代码如下
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))){ Message_Box messageBox = new Message_Box(null,course,null); if (Exist_Course(course)) listCourse.add(course); } 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 grade = new Grade_Exam(Line[3]); Message_Box messageBox = new Message_Box(student,course,grade); 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("考试")) { Grade grade = new Grade_daily(Line[3],Line[4]); Message_Box messageBox = new Message_Box(student,course,grade); 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 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 { 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.get_TotalGrade(); } 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) { if (course.getGrade_Way().equals("考察")) { System.out.println(course.getName() + " " + getAvgExamScore(courseStudentSelects) + " " + getAvgTotalCourse(courseStudentSelects)); } else { System.out.println(course.getName() + " " + getAvgDailyScore(courseStudentSelects) + " " + getAvgExamScore(courseStudentSelects) + " " + 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.get_TotalGrade(); } return (int)(1.0*total/courseStudentSelects.size()); } private int getAvgDailyScore(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += ((Grade_daily)messageBox.grade).get_DailyGrade(); } return (int)(1.0*total/courseStudentSelects.size()); } private int getAvgExamScore(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += messageBox.grade.get_ExamGrade(); } 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.get_TotalGrade(); } 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 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 = "(考试|考察)"; //courseInput用于定义课程信息模式(正则表达式) /*这里的正则表达式考虑到了长度为二的情况吗? 这里的测试测试点似乎并不考虑这给error问题*/ String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"; String scoreInput_2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching; public int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s) || s.matches(scoreInput_2)) { return 2; } return 0; } private boolean matchingCourse(String s) { return s.matches(courseInput); } private boolean matchingScore(String s) { //System.out.println(match); return s.matches(scoreInput); } } } 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; @Override 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; } } class Message_Box { Student student; Course course; Grade grade; Message_Box(Student student , Course course , Grade grade) { this.student = student; this.course = course; this.grade = grade; } } 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 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; } } abstract class Grade { private int Exam; public abstract int get_TotalGrade(); public abstract int get_ExamGrade(); public void setExam(int exam) { this.Exam = exam; } public int getExam() { return Exam; } } class Grade_Exam extends Grade{ Grade_Exam(String Exam) { setExam(Integer.parseInt(Exam)); } public int get_TotalGrade() { return (int)(this.getExam()*1.0); } public int get_ExamGrade() { return this.getExam(); } } class Grade_daily extends Grade{ Grade_daily(String Daily , String Exam) { setDaily(Integer.parseInt(Daily)); setExam(Integer.parseInt(Exam)); } private int Daily; public int get_TotalGrade() { return (int)(this.getDaily()*0.3 + this.getExam()*0.7); } public int get_DailyGrade() { return this.getDaily(); } public int get_ExamGrade() { return this.getExam(); } public void setDaily(int daily) { Daily = daily; } public int getDaily() { return Daily; } }
测试点如下
分析
第一部分:首先对输入的信息进行格式对比,进行相对应的信息做出相对应的信息处理。
第二部分:通过遍历信息记录类的链表实现查找对应的学生和对应的课程。
第三毒粉:输出对应的学生和课程以及班级总分,平时分,考试分,平均分等信息。
难点
这一题,主要是在于数据结构的处理。按一般的理解我们会把学生的成绩和信息与课程相互关联,这样虽然是符合一般人的认知——即一个单独的学生要有他自己所报的课程,一个课程也得要有自己所报的学生,会让我们认为Student类里面得要有他自己的课程链表。Course类里面也得要有它自己所报的学生,这样会大大加大我们代码的负担,使得整体代码变得不再整洁和明了。
总结
幸运的是,老师上课的时候给我们讲了一下这个题目,提出要单独建一个信息记录类来存储输入的信息,通过遍历这个信息记录类来找到对应的学生信息和对应的课程信息,大大的减少了学生和课程遍历的差异,极大的减少了代码的复杂程度。
但是,如果输入的信息足够的大,每次遍历所有的信息记录链表都会造成大量的时间浪费,分散了计算机的算力。在对应极大的信息输入的时候,应该要考虑使用别的方法来实现信息的存储和信息的调用。
这里的是因为给的测试点案例不是很多,一般是看不出有这个运行时长的问题。
之前我通过我自己的方法,把Student和Course类进行相互关联,使得我的代码变得异常的复杂,再而通过我拆东墙补西墙的代码习惯——暂时需要啥方法就创建啥方法的作为,也让我的代码成为了“屎山代码”。最多的时候也就只有71测试点的分数。
最后还是通过利用老师的结构去写,很快的解决了所有的问题,通过了所有的测试点。
面向对象程序设计A---第7次题目集:7-3 课程成绩统计程序-2
难度
****
类图
SourceMonitor
代码如下
import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; 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))){ Message_Box messageBox = new Message_Box(null,course,null); if (Exist_Course(course)) listCourse.add(course); } 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 grade = new Grade_Exam(Line[3]); Message_Box messageBox = new Message_Box(student,course,grade); 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 grade = new Grade_daily(Line[3],Line[4]); Message_Box messageBox = new Message_Box(student,course,grade); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else if (course.getGrade_Way().equals("实验") && Line.length-4 == Integer.parseInt(Line[3])) { Grade grade = new Grade_Lab(Line); Message_Box messageBox = new Message_Box(student,course,grade); 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 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.get_TotalGrade(); } 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) { if (course.getGrade_Way().equals("考察")) { System.out.println(course.getName() + " " + getAvgExamScore(courseStudentSelects) + " " + getAvgTotalCourse(courseStudentSelects)); } else if (course.getGrade_Way().equals("考试")){ System.out.println(course.getName() + " " + getAvgDailyScore(courseStudentSelects) + " " + getAvgExamScore(courseStudentSelects) + " " + getAvgTotalCourse(courseStudentSelects)); } else if (course.getGrade_Way().equals("实验")) { 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.get_TotalGrade(); } return (int)(1.0*total/courseStudentSelects.size()); } private int getAvgDailyScore(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += ((Grade_daily)messageBox.grade).get_DailyGrade(); } return (int)(1.0*total/courseStudentSelects.size()); } private int getAvgExamScore(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += messageBox.grade.get_ExamGrade(); } 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.get_TotalGrade(); } 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个0-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 = "(考试|考察|实验)"; //courseInput用于定义课程信息模式(正则表达式) /*这里的正则表达式考虑到了长度为二的情况吗? 这里的测试测试点似乎并不考虑这给error问题*/ String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"; String scoreInput_2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching; String lab_Input_0 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + Lab_Times_Matching; public int matchingInput(String s) { String[] input = s.split(" "); String Lab_up = ""; if (input.length >= 5) { Lab_up = input[0] + " " + input[1] + " " + input[2] + " " + input[3]; } if (matchingCourse(s)) { return 1; } if (matchingScore(s) || s.matches(scoreInput_2)) { return 2; } if (matching_Lab(Lab_up)){ //输入符合实验的前提条件 int number = Integer.parseInt(input[3]); for (int i = 4 ; i < input.length ; i++) { //查看后续条件是否符合 if (!input[i].matches(scoreMatching)) { //如果找到一个不符合的 return 0; } } return 2; } return 0; } private boolean matchingCourse(String s) { return s.matches(courseInput); } private boolean matchingScore(String s) { //System.out.println(match); return s.matches(scoreInput); } private boolean matching_Lab (String s) { return s.matches(lab_Input_0); } } } 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; @Override 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; } } 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; } } abstract class Grade { private int Exam; public abstract int get_TotalGrade(); public abstract int get_ExamGrade(); public void setExam(int exam) { this.Exam = exam; } public int getExam() { return Exam; } } class Grade_daily extends Grade { Grade_daily(String Daily , String Exam) { setDaily(Integer.parseInt(Daily)); setExam(Integer.parseInt(Exam)); } private int Daily; public int get_TotalGrade() { return (int)(this.getDaily()*0.3 + this.getExam()*0.7); } public int get_DailyGrade() { return this.getDaily(); } public int get_ExamGrade() { return this.getExam(); } public void setDaily(int daily) { Daily = daily; } public int getDaily() { return Daily; } } class Grade_Exam extends Grade{ Grade_Exam(String Exam) { setExam(Integer.parseInt(Exam)); } public int get_TotalGrade() { return (int)(this.getExam()*1.0); } public int get_ExamGrade() { return this.getExam(); } } class Grade_Lab extends Grade{ private int Laboratory = 0; private int times; Grade_Lab(String[] Inputs) { times=Integer.parseInt(Inputs[3]); for (int i = 4 ; i < Inputs.length; i++) { Laboratory += Integer.parseInt(Inputs[i]); } } @Override public int get_TotalGrade() { return (int)(1.0*Laboratory/times); } @Override public int get_ExamGrade() { return 0; } } class Message_Box { Student student; Course course; Grade grade; Message_Box(Student student , Course course , Grade grade) { this.student = student; this.course = course; this.grade = grade; } }
测试点如下
分析
第一部分:首先对输入的信息进行格式对比,进行相对应的信息做出相对应的信息处理。
第二部分:通过遍历信息记录类的链表实现查找对应的学生和对应的课程。
第三毒粉:输出对应的学生和课程以及班级总分,平时分,考试分,平均分等信息。
难点
这里的难点和上面的PTA—6的学生管理系统差不多,唯一要注意的是这里多出了一个新的信息输入,得要对原来的信息处理做出改进,对于正则表达式得要有一定的区分和一定的了解和熟练。
总结
这里和PTA—6的学生管理系统的区别不大,但是得要额外的注意输入信息的处理,必须对新的信息输入要有正确的判别和正确的分析,处理上面也要步步小心。
面向对象程序设计A---第8次题目集:7-2 课程成绩统计程序-3
难度
******
类图
SourceMonitor
代码如下
import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; 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.0); } 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); 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); 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); 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) { double total = 0; for (Message_Box messageBox : stuCourseSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(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) { double total = 0; for (Message_Box messageBox : courseStudentSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(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) { double total = 0; for (Message_Box messageBox : classroomSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(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; 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<>(); @Override 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 { for (int i = 0 ; i < num ; i++){ grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[i+3]),course.getWeight(i))); } } } public double get_grade_Total() { double total = 0; for (Grade_itemize gradeItemize : grade_itemizes) { total += gradeItemize.get_grade_One(); } return (int)(total); } } class Grade_itemize { private int score = 0; private double date = 0; Grade_itemize(int score , double date) { this.score = score; this.date = date; } public double get_grade_One() { return score*date; } }
测试点如下
分析
第一部分:首先对输入的信息进行格式对比,进行相对应的信息做出相对应的信息处理。
第二部分:通过遍历信息记录类的链表实现查找对应的学生和对应的课程。
第三毒粉:输出对应的学生和课程以及班级总分,平时分,考试分,平均分等信息。
难点
在处理数据的时候必须得要区分数据处理的先后顺序和数据处理的方法
题目要求如下
为避免四舍五入误差,
计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。
学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。
如果对其前后进行对调的话,结果就会有很多的不同,我这一题就得了32分(一半的分)全部的问题都跟多个学生,多个班级,多个课程和多个课程类型有关。
总结
因为不知道错在哪里,所有现在无法给出很肯定的容错点
值得注意的是因为输入的数据都基本上都是多数据的,所有对每种的信息输入都变得有迹可寻,编写上大体是没有啥太大问题。慢慢用时间去磨的话还是可以做出来的。
总结
- 一定要审题清楚,不要盲目的去按照自己的意思去写,而是按着甲方的需求去写。
- 对于这种代码需求量比较大的代码,必须得要留有足够的时间去慢慢磨它,慢慢的去消化和吸收。
- 在写题目之前必须得先要考虑到要以什么样的结构去实现相对应的功能,不要以自己所认为的结构去写,可以去自己去尝试尝试,但是的要有理论基础,要不然会浪费大量的时间去(之前我就是因为这样子浪费了两三天的时间去写,只拿到了71分,但是我还是建议我们多多尝试,多多练习,没有最好的代码,只有最合适的代码,说不定你自己的想法就是那个命中注定,即使是最差的想法,最差的结构,最差的算法,我们也可以练习我们的代码思维和编写代码是能力)。