前言
好久不见,本次Blog主要总结这几个月来的大作业情况、以及学习情况。本次Blog也是最后一次Blog,索性做一个期末总结。话不多说,开始~~
大作业:这三次的大作业相较于菜单系列主要知识点没有变化,甚至在难度方面也低于菜单系列(主要本次两次迭代根本没有在已提供的类图上发生变化,故在设计思路上也没有难点)。故此次对于大作业的总结主要在细节方面(如HashMap数组的排序方式、对于抽象类子类但是创建时为父类的后续识别方式、数据处理流程以及方式等)以及一些测试点难点。
学习分析:这段时间学习的知识点很少,主要停留在对于javaFx的学习,以及对于前面学习过的设计思路、类的关系的复习。
学习总分析:这个学期接触了Java这门神奇的语言———一门把现实中的事务都抽象成为程序设计中的“对象”,其基本思想是一切皆对象,是一种“自下而上”的设计语言,先设计组件,再完成拼装的语言。其三大基本特征是——封装、继承和多态。随后,我接触到了类的设计,以及类设计的七大原则——开闭原则、单一职责原则、依赖倒置原则、里氏替换原则、接口隔离原则、迪米特法则以及组合/聚合复用原则。随后,就是了解到类之间的关系——依赖、关联、聚合以及组合关系。再解除了类之间的继承以及接口关系。最后接触到面向对象设计原理,这也是学习时长最长的部分。这一部分,主要围绕类的设计展开,七大类的设计已在前文提到,此期间我了解到程序设计的多样性,每个人都会有自己的思路,合理即可。最后,我学习了可视化界面设计,即javaFx的运用,该方面我的学习程度较低,更多的是配合网络查找资料进行设计,故可总结的方面较少。
好了,前言到这里就结束了,让我们开始我们的正文吧~~
设计与分析
第六次大作业
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃
参考类图:
输入样例1:
仅有课程。例如:
java 必修 考试
数据结构 选修 考试
形式与政治 选修 考察
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
数据结构 has no grades yet
形式与政治 has no grades yet
输入样例2:
单门考试课程 单个学生。例如:
java 必修 考试
20201103 张三 java 20 40
end
输出样例2:
在这里给出相应的输出。例如:
20201103 张三 34
java 20 40 34
202011 34
输入样例3:
单门考察课程 单个学生。例如:
java 选修 考察
20201103 张三 java 40
end
输出样例3:
在这里给出相应的输出。例如:
20201103 张三 40
java 40 40
202011 40
输入样例4:
考试课程 单个学生 不匹配的考核方式。例如:
java 必修 考试
20201103 张三 java 20
end
输出样例4:
在这里给出相应的输出。例如:
20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet
输入样例5:
单门课程,单个学生,课程类型与考核类型不匹配。例如:
java 必修 考察
20201103 张三 java 40
end
输出样例5:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
java does not exist
20201103 张三 did not take any exams
202011 has no grades yet
输入样例6:
单门课程,多个学生。例如:
java 选修 考察
20201103 李四 java 60
20201104 王五 java 60
20201101 张三 java 40
end
输出样例6:
在这里给出相应的输出。例如:
20201101 张三 40
20201103 李四 60
20201104 王五 60
java 53 53
202011 53
输入样例7:
单门课程,单个学生,课程类型与考核类型不匹配。例如:
形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201103 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201103 李四 java 60
20201103 李四 数据库 70 78
end
输出样例7:
在这里给出相应的输出。例如:
20201103 李四 73
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73
输入样例8:
单门课程,单个学生,成绩越界。例如:
数据结构 选修 考察
20201103 李四 数据结构 101
end
输出样例8:
在这里给出相应的输出。例如:
wrong format
数据结构 has no grades yet
输入样例9:
多门课程,多个学生,多个成绩。例如:
形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201205 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201102 王五 java 60
20201211 张三 数据库 70 78
end
输出样例9:
在这里给出相应的输出。例如:
20201102 王五 60
20201103 李四 87
20201205 李四 70
20201211 张三 75
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73
202012 72
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); messageGetAndPrint.print = new Print(); for(;;){ String message = in.readLine(); if(message.equals("end")) { messageGetAndPrint.print.personPrint(messageGetAndPrint.students , messageGetAndPrint.courseSelections); messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses , messageGetAndPrint.courseSelections); messageGetAndPrint.print.classPrint(messageGetAndPrint.classes , messageGetAndPrint.courseSelections); break; } messageGetAndPrint.getMessage(message); } } } class Class { private String classNum; HashMap<String , Student> students; Class(String classNum) { setClassNum(classNum); } public void setClassNum(String classNum) { this.classNum = classNum; } public String getClassNum() { return classNum; } public void addStudent(Student student) { students.put(student.getStudentNum() , student); } public void deleteStudent(String studentNum) { students.remove(studentNum); } } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } class Course { private String className; private int classQuality; private int assessmentMethodology; Course(String className , int classQuality , int assessmentMethodology) { setClassName(className); setClassQuality(classQuality); setAssessmentMethodology(assessmentMethodology); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public int getClassQuality() { return classQuality; } public void setClassQuality(int classQuality) { this.classQuality = classQuality; } public int getAssessmentMethodology() { return assessmentMethodology; } public void setAssessmentMethodology(int assessmentMethodology) { this.assessmentMethodology = assessmentMethodology; } } class CourseSelection { Student student; Course course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } class GradeA extends Grade { private int finalGrade; private int usualGrade; GradeA(int finalGrade , int usualGrade) { setFinalGrade(finalGrade); setUsualGrade(usualGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } public void setUsualGrade(int usualGrade) { this.usualGrade = usualGrade; } public int getUsualGrade() { return usualGrade; } @Override void getAllGrade() { allGrade = (int) (finalGrade*0.7+usualGrade*0.3); } } class GradeB extends Grade { private int finalGrade; GradeB(int finalGrade) { setFinalGrade(finalGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } @Override void getAllGrade() { allGrade = finalGrade; } } class Print { public void personPrint(HashMap<String , Student> students , ArrayList<CourseSelection> courseSelections) { Set<String> set = students.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for (CourseSelection courseSelection : courseSelections) { if (students.get(key).getStudentNum().equals(courseSelection.student.getStudentNum())) { if(y == -1) y = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" did not take any exams"); } if(y != -1) { x = x/y; System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" "+x); } } } public void coursePrint(HashMap<String , Course> courses , ArrayList<CourseSelection> courseSelections) { List<String> list = courses.keySet().stream().collect(Collectors.toList()); Collections.sort(list , new SoftName()); for(String key:list) { int x = 0 , y = -1 , f = 0 , u = 0 , uy = -1; for (CourseSelection courseSelection : courseSelections) { if (courses.get(key).getClassName().equals(courseSelection.course.getClassName())) { if(y == -1) y = 0; if(courses.get(key).getAssessmentMethodology() == 1 && uy == -1) uy = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; if(courseSelection.grade instanceof GradeA) { f += ((GradeA) courseSelection.grade).getFinalGrade(); u += ((GradeA) courseSelection.grade).getUsualGrade(); uy++; } if(courseSelection.grade instanceof GradeB) { f += ((GradeB) courseSelection.grade).getFinalGrade(); } y++; } } if(y == -1) { System.out.println(courses.get(key).getClassName()+" has no grades yet"); } x = x/y; f = f/y; if(y != -1 && uy == -1) { System.out.println(courses.get(key).getClassName()+" "+f+" "+x); } if(y != -1 && uy != -1) { u = u/uy; System.out.println(courses.get(key).getClassName()+" "+u+" "+f+" "+x); } } } public void classPrint(HashMap<String , Class> classes , ArrayList<CourseSelection> courseSelections) { Set<String> set = classes.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for(CourseSelection courseSelection : courseSelections) { if(classes.get(key).students.containsKey(courseSelection.student.getStudentNum())) { if(y == -1) { y = 0; } courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(classes.get(key).getClassNum()+" has no grades yet"); return; } x = x/y; System.out.println(classes.get(key).getClassNum()+" "+x); } } public void wrongFormat() { System.out.println("wrong format"); } public void courseExist(String name) { System.out.println(name+" does not exist"); } public void courseMatch(String studentNum , String studentName) { System.out.println(studentNum+" "+studentName+" : access mode mismatch"); } public void courseMatch(String name) { System.out.println(name+" : course type & access mode mismatch"); } static class SoftName implements Comparator<String>{ public int compare(String name1 , String name2) { Comparator<Object> compare = Collator.getInstance(Locale.CHINA); return compare.compare(name1 , name2); } } } class MessageGetAndPrint { Print print; HashMap<String , Class> classes = new HashMap<>(); HashMap<String , Student> students = new HashMap<>(); HashMap<String , Course> courses = new HashMap<>(); ArrayList<CourseSelection> courseSelections = new ArrayList<>(); public void getMessage(String getInput) { String[] message = getInput.split(" "); if(getInput.matches("^(\\S{0,10})( )(必修|选修)( )(考试|考察)$")) { int i = 0, j = 0; if(message[1].equals("必修")) { i = 1; } if(message[1].equals("选修")) { i = 2; } if(message[2].equals("考试")) { j = 1; } if(message[2].equals("考察")) { j = 2; } if(i == 1 && j != 1) { print.courseMatch(message[0]); return; } if(courses.containsKey(message[0])) { return; } Course course = new Course(message[0], i, j); courses.put(message[0], course); return; } if(getInput.matches("^([0-9]{8})( )(\\S{0,10})( )(\\S{0,10})( )([0-9]|[1-9][0-9]|10{2})( )([0-9]|[1-9][0-9]|10{2})$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).students.put(message[0], student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 1) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[4]); int usualGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeA(finalGrade , usualGrade); courseSelections.add(courseSelection); return; } if(getInput.matches("^([0-9]{8})( )(\\S{0,10})( )(\\S{0,10})( )([0-9]|[1-9][0-9]|10{2})$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 2) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeB(finalGrade); courseSelections.add(courseSelection); } else { print.wrongFormat(); } } }
Metrics Details For File 'Main.java'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory D:\java\javademo\src\
Project Name blog3-1
Checkpoint Name Baseline
File Name Main.java
Lines 351
Statements 256
Percent Branch Statements 16.8
Method Call Statements 115
Percent Lines with Comments 0.0
Classes and Interfaces 11
Methods per Class 3.36
Average Statements per Method 4.86
Line Number of Most Complex Method 256
Name of Most Complex Method MessageGetAndPrint.getMessage()
Maximum Complexity 26
Line Number of Deepest Block 182
Maximum Block Depth 6
Average Block Depth 2.50
Average Complexity 2.38
--------------------------------------------------------------------------------------------
Most Complex Methods in 9 Class(es): Complexity, Statements, Max Depth, Calls
Class.addStudent() 1, 1, 2, 1
Class.Class() 1, 1, 2, 1
Class.deleteStudent() 1, 1, 2, 1
Class.getClassNum() 1, 1, 2, 0
Class.setClassNum() 1, 1, 2, 0
Course.Course() 1, 3, 2, 3
Course.getAssessmentMethodology() 1, 1, 2, 0
Course.getClassName() 1, 1, 2, 0
Course.getClassQuality() 1, 1, 2, 0
Course.setAssessmentMethodology() 1, 1, 2, 0
Course.setClassName() 1, 1, 2, 0
Course.setClassQuality() 1, 1, 2, 0
GradeA.getAllGrade() 1, 1, 2, 0
GradeA.getFinalGrade() 1, 1, 2, 0
GradeA.getUsualGrade() 1, 1, 2, 0
GradeA.GradeA() 1, 2, 2, 2
GradeA.setFinalGrade() 1, 1, 2, 0
GradeA.setUsualGrade() 1, 1, 2, 0
GradeB.getAllGrade() 1, 1, 2, 0
GradeB.getFinalGrade() 1, 1, 2, 0
GradeB.GradeB() 1, 1, 2, 1
GradeB.setFinalGrade() 1, 1, 2, 0
Main.main() 3, 10, 4, 6
MessageGetAndPrint.getMessage() 26, 71, 5, 51
Print.classPrint() 6, 17, 6, 10
Print.courseExist() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.coursePrint() 14, 28, 6, 15
Print.personPrint() 7, 17, 5, 11
Print.wrongFormat() 1, 1, 2, 1
SoftName.compare() 1, 2, 3, 2
Student.getName() 1, 1, 2, 0
Student.getStudentNum() 1, 1, 2, 0
Student.setName() 1, 1, 2, 0
Student.setStudentNum() 1, 1, 2, 0
Student.Student() 1, 2, 2, 2
--------------------------------------------------------------------------------------------
Block Depth Statements
0 16
1 59
2 56
3 62
4 38
5 20
6 5
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
分析:
首先聊聊本题的设计思路,本题的设计思路按照老师给的类图展开——班级类、学生类、课程类、选课系统类、,学生类聚合班级类,选课系统类由学生类、成绩类、课程类组合,这样处理可表示一个学生选了一门课,同时2个成绩类继承一个抽象成绩类,可表示2种考核方式,组合不同的成绩类可表示不同考核方式,降低类之间的耦合。本题的难点有如下几个难点:1. 在输入课或者输入成绩时会出现错误情况,如何保证学生信息已处理的情况下,保存学生信息但不储存选课信息2. 在输出成绩的时候如何排序,同时在课程存在中文的情况下如何排序。第一个问题我的处理方法为,分别创建学生、课程、班级HashMap数组,选课系统ArrayList数组,在输入课时,数据没有问题的情况下直接加入课程数组,关键在于输入成绩时,在数据出问题情况下(如课程考核方式不匹配)我会将学生、班级信息分别加入对应数组,但选课系统不创建,如信息没问题再创建加入选课系统数组。在输出时,通过导出班级、课程、学生数组中的信息,一个一个在选课系统中查找信息,最后处理输出。对于排序,我的处理方式为对创建的学生、班级、课程类数组所有的Key导出储存在新数组中,再对该数组排序,在通过用Key提取Value从而达到排序方式。对于课程的排序,我运用了Collections.sort()方法,再覆写compare方法:
public int compare(String name1 , String name2) {
Comparator<Object> compare = Collator.getInstance(Locale.CHINA);
return compare.compare(name1 , name2);
}即可完成对中文的排序。除此之外,该题还要注意正则表达式的处理,如输入课,必需是必修/选修 考试/考察的格式,成绩的范围必修是0-100,学生学号、名字以及课程名字都有长度范围,同时必修课可忽略后面的考试。最后,注意输出时数据处理即可,推荐全部用Int类型处理即可。
第七次大作业
课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩的平均分
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修、实验
考核方式输入选项:考试、考察、实验
考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
考试/考查课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩
实验次数至少4次,不超过9次
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
以上信息的相关约束:
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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
输入样例1:
在这里给出一组输入。例如:
java 实验 实验
20201103 张三 java 4 70 80 90
end
输出样例1:
在这里给出相应的输出。例如:
20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验
20201103 张三 java 3 70 80 90
end
输出样例2:
在这里给出相应的输出。例如:
wrong format
java has no grades yet
输入样例3:
在这里给出一组输入。例如:
java 必修 实验
20201103 张三 java 3 70 80 90 100
end
输出样例3:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例4:
在这里给出一组输入。例如:
java 必修 实验
20201103 张三 java 4 70 80 90 105
end
输出样例4:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例5:
在这里给出一组输入。例如:
java 选修 考察
C语言 选修 考察
java实验 实验 实验
编译原理 必修 考试
20201101 王五 C语言 76
20201216 李四 C语言 78
20201307 张少军 编译原理 82 84
20201103 张三 java实验 4 70 80 90 100
20201118 郑觉先 java 80
20201328 刘和宇 java 77
20201220 朱重九 java实验 4 60 60 80 80
20201132 王萍 C语言 40
20201302 李梦涵 C语言 68
20201325 崔瑾 编译原理 80 84
20201213 黄红 java 82
20201209 赵仙芝 java 76
end
输出样例5:
在这里给出相应的输出。例如:
20201101 王五 76
20201103 张三 85
20201118 郑觉先 80
20201132 王萍 40
20201209 赵仙芝 76
20201213 黄红 82
20201216 李四 78
20201220 朱重九 70
20201302 李梦涵 68
20201307 张少军 83
20201325 崔瑾 82
20201328 刘和宇 77
C语言 65 65
java 78 78
java实验 77
编译原理 81 84 82
202011 70
202012 76
202013 77
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); messageGetAndPrint.print = new Print(); for(;;){ String message = in.readLine(); if(message.equals("end")) { messageGetAndPrint.print.personPrint(messageGetAndPrint.students , messageGetAndPrint.courseSelections); messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses , messageGetAndPrint.courseSelections); messageGetAndPrint.print.classPrint(messageGetAndPrint.classes , messageGetAndPrint.courseSelections); break; } messageGetAndPrint.getMessage(message); } } } class Class { private String classNum; HashMap<String , Student> students; Class(String classNum) { setClassNum(classNum); } public void setClassNum(String classNum) { this.classNum = classNum; } public String getClassNum() { return classNum; } public void addStudent(Student student) { students.put(student.getStudentNum() , student); } public void deleteStudent(String studentNum) { students.remove(studentNum); } } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } class Course { private String className; private int classQuality; private int assessmentMethodology; Course(String className , int classQuality , int assessmentMethodology) { setClassName(className); setClassQuality(classQuality); setAssessmentMethodology(assessmentMethodology); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public int getClassQuality() { return classQuality; } public void setClassQuality(int classQuality) { this.classQuality = classQuality; } public int getAssessmentMethodology() { return assessmentMethodology; } public void setAssessmentMethodology(int assessmentMethodology) { this.assessmentMethodology = assessmentMethodology; } } class CourseSelection { Student student; Course course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } class GradeA extends Grade { private int finalGrade; private int usualGrade; GradeA(int finalGrade , int usualGrade) { setFinalGrade(finalGrade); setUsualGrade(usualGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } public void setUsualGrade(int usualGrade) { this.usualGrade = usualGrade; } public int getUsualGrade() { return usualGrade; } @Override void getAllGrade() { allGrade = (int) (finalGrade*0.7+usualGrade*0.3); } } class GradeB extends Grade { private int finalGrade; GradeB(int finalGrade) { setFinalGrade(finalGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } @Override void getAllGrade() { allGrade = finalGrade; } } class GradeC extends Grade { ArrayList<Integer> usualGrades; GradeC(ArrayList<Integer> usualGrades) { this.usualGrades = usualGrades; } @Override void getAllGrade() { allGrade = 0; for(int x:usualGrades){ allGrade+=x; } allGrade = allGrade/usualGrades.size(); } } class Print { public void personPrint(HashMap<String , Student> students , ArrayList<CourseSelection> courseSelections) { Set<String> set = students.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for (CourseSelection courseSelection : courseSelections) { if (students.get(key).getStudentNum().equals(courseSelection.student.getStudentNum())) { if(y == -1) y = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" did not take any exams"); continue; } x = x / y; System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" "+x); } } public void coursePrint(HashMap<String , Course> courses , ArrayList<CourseSelection> courseSelections) { List<String> list = courses.keySet().stream().collect(Collectors.toList()); Collections.sort(list , new SoftName()); for(String key:list) { int x = 0 , y = -1 , f = 0 , u = 0 , uy = -1 , s = -1; for (CourseSelection courseSelection : courseSelections) { if (courses.get(key).getClassName().equals(courseSelection.course.getClassName())) { if(y == -1) y = 0; if(courses.get(key).getAssessmentMethodology() == 1 && uy == -1) uy = 0; if(courses.get(key).getAssessmentMethodology() == 3 && s == -1) s = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; if(courseSelection.grade instanceof GradeA) { f += ((GradeA) courseSelection.grade).getFinalGrade(); u += ((GradeA) courseSelection.grade).getUsualGrade(); uy++; } if(courseSelection.grade instanceof GradeB) { f += ((GradeB) courseSelection.grade).getFinalGrade(); } y++; } } if(y == -1) { System.out.println(courses.get(key).getClassName()+" has no grades yet"); continue; } x = x/y; f = f/y; if(s == 0) { System.out.println(courses.get(key).getClassName()+" "+x); continue; } if(uy == -1) { System.out.println(courses.get(key).getClassName()+" "+f+" "+x); } if(uy != -1) { u = u/uy; System.out.println(courses.get(key).getClassName()+" "+u+" "+f+" "+x); } } } public void classPrint(HashMap<String , Class> classes , ArrayList<CourseSelection> courseSelections) { Set<String> set = classes.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for(CourseSelection courseSelection : courseSelections) { if(classes.get(key).students.containsKey(courseSelection.student.getStudentNum())) { if(y == -1) { y = 0; } courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(classes.get(key).getClassNum()+" has no grades yet"); continue; } x = x/y; System.out.println(classes.get(key).getClassNum()+" "+x); } } public void wrongFormat() { System.out.println("wrong format"); } public void courseExist(String name) { System.out.println(name+" does not exist"); } public void courseMatch(String studentNum , String studentName) { System.out.println(studentNum+" "+studentName+" : access mode mismatch"); } public void courseMatch(String name) { System.out.println(name+" : course type & access mode mismatch"); } static class SoftName implements Comparator<String>{ public int compare(String name1 , String name2) { Comparator<Object> compare = Collator.getInstance(Locale.CHINA); return compare.compare(name1 , name2); } } } class MessageGetAndPrint { Print print; HashMap<String , Class> classes = new HashMap<>(); HashMap<String , Student> students = new HashMap<>(); HashMap<String , Course> courses = new HashMap<>(); ArrayList<CourseSelection> courseSelections = new ArrayList<>(); public void getMessage(String getInput) { String[] message = getInput.split(" "); if(getInput.matches("^(\\S{1,10})( )(必修)$")) { int i = 1, j = 1; if(courses.containsKey(message[0])) { return; } Course course = new Course(message[0], i, j); courses.put(message[0], course); return; } if(getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$")) { int i = 0, j = 0; if(message[1].equals("必修")) { i = 1; } if(message[1].equals("选修")) { i = 2; } if(message[1].equals("实验")) { i = 3; } if(message[2].equals("考试")) { j = 1; } if(message[2].equals("考察")) { j = 2; } if(message[2].equals("实验")) { j = 3; } if(i == 1 && j != 1) { print.courseMatch(message[0]); return; } if(i == 3 && j != 3) { print.courseMatch(message[0]); return; } if(i != 3 && j == 3) { print.courseMatch(message[0]); return; } if(courses.containsKey(message[0])) { return; } Course course = new Course(message[0], i, j); courses.put(message[0], course); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).students.put(message[0], student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 1) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[4]); int usualGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeA(finalGrade , usualGrade); courseSelections.add(courseSelection); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|10{2})$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 2) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeB(finalGrade); courseSelections.add(courseSelection); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((([0-9]|[1-9][0-9]|100)( ))+)([0-9]|[1-9][0-9]|100)$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 3) { print.courseMatch(message[0] , message[1]); return; } int usualNum = Integer.parseInt(message[3]); if(message.length-4 != usualNum) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); ArrayList<Integer> usualGrades = new ArrayList<>(); for(int i = 1;i <= usualNum;i++) { usualGrades.add(Integer.parseInt(message[3+i])); } courseSelection.grade = new GradeC(usualGrades); courseSelections.add(courseSelection); return; } print.wrongFormat(); } }
Metrics Details For File 'Main.java'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory D:\java\javademo\src\
Project Name blog3-2
Checkpoint Name Baseline
File Name Main.java
Lines 429
Statements 316
Percent Branch Statements 18.4
Method Call Statements 150
Percent Lines with Comments 0.0
Classes and Interfaces 12
Methods per Class 3.25
Average Statements per Method 6.03
Line Number of Most Complex Method 275
Name of Most Complex Method MessageGetAndPrint.getMessage()
Maximum Complexity 43
Line Number of Deepest Block 197
Maximum Block Depth 6
Average Block Depth 2.61
Average Complexity 2.77
--------------------------------------------------------------------------------------------
Most Complex Methods in 10 Class(es): Complexity, Statements, Max Depth, Calls
Class.addStudent() 1, 1, 2, 1
Class.Class() 1, 1, 2, 1
Class.deleteStudent() 1, 1, 2, 1
Class.getClassNum() 1, 1, 2, 0
Class.setClassNum() 1, 1, 2, 0
Course.Course() 1, 3, 2, 3
Course.getAssessmentMethodology() 1, 1, 2, 0
Course.getClassName() 1, 1, 2, 0
Course.getClassQuality() 1, 1, 2, 0
Course.setAssessmentMethodology() 1, 1, 2, 0
Course.setClassName() 1, 1, 2, 0
Course.setClassQuality() 1, 1, 2, 0
GradeA.getAllGrade() 1, 1, 2, 0
GradeA.getFinalGrade() 1, 1, 2, 0
GradeA.getUsualGrade() 1, 1, 2, 0
GradeA.GradeA() 1, 2, 2, 2
GradeA.setFinalGrade() 1, 1, 2, 0
GradeA.setUsualGrade() 1, 1, 2, 0
GradeB.getAllGrade() 1, 1, 2, 0
GradeB.getFinalGrade() 1, 1, 2, 0
GradeB.GradeB() 1, 1, 2, 1
GradeB.setFinalGrade() 1, 1, 2, 0
GradeC.getAllGrade() 2, 4, 3, 0
GradeC.GradeC() 1, 1, 2, 0
Main.main() 3, 10, 4, 6
MessageGetAndPrint.getMessage() 43, 119, 5, 82
Print.classPrint() 6, 16, 6, 10
Print.courseExist() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.coursePrint() 15, 32, 6, 19
Print.personPrint() 6, 16, 5, 11
Print.wrongFormat() 1, 1, 2, 1
SoftName.compare() 1, 2, 3, 2
Student.getName() 1, 1, 2, 0
Student.getStudentNum() 1, 1, 2, 0
Student.setName() 1, 1, 2, 0
Student.setStudentNum() 1, 1, 2, 0
Student.Student() 1, 2, 2, 2
--------------------------------------------------------------------------------------------
Block Depth Statements
0 17
1 63
2 62
3 92
4 54
5 23
6 5
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
分析:
该题为上一道的迭代,变化不是很大,主要增加了一个实验课的情况,该题的难点在于正则表达式对于数据的处理,以及如何判断实验课的实验次数和输入的实验成绩数不匹配的情况。跟上一题类似,我增加了一个成绩类继承抽象成绩类,用于对应实验课的情况,关于数据储存跟之前的储存方式一致。对于实验情况的正则表达式,要保证必需有实验次数,成绩数量至少一个,所以本题我的正则表达式为"^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((([0-9]|[1-9][0-9]|100)( ))+)([0-9]|[1-9][0-9]|100)$",对于实验课的成绩处理,我在对于实验课的成绩类中加入ArrayList数组,用于存储实验成绩。对于判断实验次数和实验成绩数是否匹配的情况,我用了一个取巧的方法,我将输入语句用split(" ")分割,再判断用分割后的数组数量减去-4是否等于实验次数。除了这些特殊情况,其他和成绩系统1相差不大。
第八次大作业
课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,
要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。
题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。
考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重
考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重
实验次数至少4次,不超过9次
课程性质输入项:必修、选修、实验
考核方式输入选项:考试、考察、实验
考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
考试/考查课程成绩信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
以上信息的相关约束:
1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】
2)学号由8位数字组成
3)姓名不超过10个字符
4)课程名称不超过10个字符
5)不特别输入班级信息,班级号是学号的前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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。
6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"
7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"
信息约束:
1)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
输入样例1:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2
end
输出样例2:
在这里给出相应的输出。例如:
java : number of scores does not match
输入样例3:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.1
end
输出样例3:
在这里给出相应的输出。例如:
java : weight value error
输入样例4:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100
end
输出样例4:
在这里给出相应的输出。例如:
20201116 张三 86
java 86
202011 86
输入样例5:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100 80
end
输出样例5:
在这里给出相应的输出。例如:
20201116 张三 : access mode mismatch
20201116 张三 did not take any exams
java has no grades yet
202011 has no grades yet
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); messageGetAndPrint.print = new Print(); for(;;){ String message = in.readLine(); if(message.equals("end")) { messageGetAndPrint.print.personPrint(messageGetAndPrint.students , messageGetAndPrint.courseSelections); messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses , messageGetAndPrint.courseSelections); messageGetAndPrint.print.classPrint(messageGetAndPrint.classes , messageGetAndPrint.courseSelections); break; } messageGetAndPrint.getMessage(message); } } } class Class { private String classNum; HashMap<String , Student> students; Class(String classNum) { setClassNum(classNum); } public void setClassNum(String classNum) { this.classNum = classNum; } public String getClassNum() { return classNum; } public void addStudent(Student student) { students.put(student.getStudentNum() , student); } } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } class Course { private String className; private int classQuality; private int assessmentMethodology; ArrayList<Float> weightFunction = new ArrayList<>(); Course(String className , int classQuality , int assessmentMethodology) { setClassName(className); setClassQuality(classQuality); setAssessmentMethodology(assessmentMethodology); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public int getClassQuality() { return classQuality; } public void setClassQuality(int classQuality) { this.classQuality = classQuality; } public int getAssessmentMethodology() { return assessmentMethodology; } public void setAssessmentMethodology(int assessmentMethodology) { this.assessmentMethodology = assessmentMethodology; } } class CourseSelection { Student student; Course course; Grade grade; } class Grade { SubItemGrades subItemGrades = new SubItemGrades(); public int getGrade(){ float allGrades = 0; for(int i = 0;i<subItemGrades.subItem.size();i++) { allGrades += subItemGrades.subItem.get(i)*subItemGrades.grades.get(i); } return (int) allGrades; } } class SubItemGrades { ArrayList<Integer> grades = new ArrayList<>(); ArrayList<Float> subItem = new ArrayList<>(); } class Print { public void personPrint(HashMap<String , Student> students , ArrayList<CourseSelection> courseSelections) { Set<String> set = students.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = 0 , z = -1; for (CourseSelection courseSelection : courseSelections) { if (students.get(key).getStudentNum().equals(courseSelection.student.getStudentNum())) { z = 0; x += courseSelection.grade.getGrade(); y++; } } if(z == -1) { System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" did not take any exams"); } if(z == 0) { x = x / y; System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" "+x); } } } public void coursePrint(HashMap<String , Course> courses , ArrayList<CourseSelection> courseSelections) { List<String> list = courses.keySet().stream().collect(Collectors.toList()); Collections.sort(list , new SoftName()); for(String key:list) { int x = 0 , y = 0 , z = -1; for (CourseSelection courseSelection : courseSelections) { if (courses.get(key).getClassName().equals(courseSelection.course.getClassName())) { z = 0; x += courseSelection.grade.getGrade(); y++; } } if(z == -1) { System.out.println(courses.get(key).getClassName()+" has no grades yet"); } if(z == 0) { x = x/y; System.out.println(courses.get(key).getClassName()+" "+x); } } } public void classPrint(HashMap<String , Class> classes , ArrayList<CourseSelection> courseSelections) { Set<String> set = classes.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = 0 , z = -1; for(CourseSelection courseSelection : courseSelections) { if(classes.get(key).students.containsKey(courseSelection.student.getStudentNum())) { z = 0; x += courseSelection.grade.getGrade(); y++; } } if(z == -1) { System.out.println(classes.get(key).getClassNum()+" has no grades yet"); } if(z == 0) { x = x/y; System.out.println(classes.get(key).getClassNum()+" "+x); } } } public void wrongFormat() { System.out.println("wrong format"); } public void courseExist(String name) { System.out.println(name+" does not exist"); } public void courseMatch(String studentNum , String studentName) { System.out.println(studentNum+" "+studentName+" : access mode mismatch"); } public void courseMatch(String name) { System.out.println(name+" : course type & access mode mismatch"); } public void numMatch(String name) { System.out.println(name+" : number of scores does not match"); } public void weightValue(String name) { System.out.println(name+" : weight value error"); } static class SoftName implements Comparator<String>{ public int compare(String name1 , String name2) { Comparator<Object> compare = Collator.getInstance(Locale.CHINA); return compare.compare(name1 , name2); } } } class MessageGetAndPrint { Print print; HashMap<String , Class> classes = new HashMap<>(); HashMap<String , Student> students = new HashMap<>(); HashMap<String , Course> courses = new HashMap<>(); ArrayList<CourseSelection> courseSelections = new ArrayList<>(); public void getMessage(String getInput) { String[] message = getInput.split(" "); if(getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$") || getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )((0.(0)+[1-9]|0.[1-9][0-9]*)( )(0.(0)+[1-9]|0.[1-9][0-9]*)$)") || getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )([4-9])((( )(0.(0)+[1-9]|0.[1-9][0-9]*|1))*)(( )(0.(0)+[1-9]|0.[1-9][0-9]*))$") ) { if(courses.containsKey(message[0])) { return; } int i = 0, j = 0; if(message[1].equals("必修")) { i = 1; } if(message[1].equals("选修")) { i = 2; } if(message[1].equals("实验")) { i = 3; } if(message[2].equals("考试")) { j = 1; } if(message[2].equals("考察")) { j = 2; } if(message[2].equals("实验")) { j = 3; } if((i == 1 && j != 1) || (i == 3 && j != 3) || (i != 3 && j == 3) ) { print.courseMatch(message[0]); return; } if((j == 1 && message.length != 5) || (j == 2 && message.length != 3) || (j == 3 && message.length - 4 != Integer.parseInt(message[3]))) { print.numMatch(message[0]); return; } if(j == 1 && Float.parseFloat(message[3])+Float.parseFloat(message[4]) != 1) { print.weightValue(message[0]); return; } if(j == 3) { float value = 0; for(int k = 0 ; k < Integer.parseInt(message[3]) ; k++) { value += Float.parseFloat(message[4+k]); } if(value>1.001||value<0.999) { print.weightValue(message[0]); return; } } Course course = new Course(message[0], i, j); if(j == 1) { course.weightFunction.add(Float.parseFloat(message[3])); course.weightFunction.add(Float.parseFloat(message[4])); } if(j == 2) course.weightFunction.add(1F); if(j == 3) { for(int k = 0 ; k < Integer.parseInt(message[3]) ; k++) { course.weightFunction.add(Float.parseFloat(message[4+k])); } } courses.put(message[0], course); } else if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)$") || getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$") || getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )((([0-9]|[1-9][0-9]|100)( ))*)([0-9]|[1-9][0-9]|100)$") ) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(message.length - 3 != courses.get(message[2]).weightFunction.size()) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); Grade grade = new Grade(); for(int i = 0 ; i < message.length - 3 ; i++) { grade.subItemGrades.grades.add(Integer.parseInt(message[3+i])); } grade.subItemGrades.subItem = courses.get(message[2]).weightFunction; courseSelection.grade = grade; courseSelections.add(courseSelection); } else print.wrongFormat(); } }
Metrics Details For File 'Main.java'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory D:\java\javademo\src\
Project Name blog3-3
Checkpoint Name Baseline
File Name Main.java
Lines 314
Statements 221
Percent Branch Statements 19.0
Method Call Statements 116
Percent Lines with Comments 0.0
Classes and Interfaces 10
Methods per Class 3.10
Average Statements per Method 5.06
Line Number of Most Complex Method 208
Name of Most Complex Method MessageGetAndPrint.getMessage()
Maximum Complexity 33
Line Number of Deepest Block 120
Maximum Block Depth 5
Average Block Depth 2.46
Average Complexity 2.72
--------------------------------------------------------------------------------------------
Most Complex Methods in 8 Class(es): Complexity, Statements, Max Depth, Calls
Class.addStudent() 1, 1, 2, 1
Class.Class() 1, 1, 2, 1
Class.getClassNum() 1, 1, 2, 0
Class.setClassNum() 1, 1, 2, 0
Course.Course() 1, 3, 2, 3
Course.getAssessmentMethodology() 1, 1, 2, 0
Course.getClassName() 1, 1, 2, 0
Course.getClassQuality() 1, 1, 2, 0
Course.setAssessmentMethodology() 1, 1, 2, 0
Course.setClassName() 1, 1, 2, 0
Course.setClassQuality() 1, 1, 2, 0
Grade.getGrade() 2, 4, 3, 3
Main.main() 3, 10, 4, 6
MessageGetAndPrint.getMessage() 33, 51, 5, 40
Print.classPrint() 6, 15, 5, 10
Print.courseExist() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.courseMatch() 1, 1, 2, 1
Print.coursePrint() 6, 14, 5, 11
Print.numMatch() 1, 1, 2, 1
Print.personPrint() 6, 15, 5, 11
Print.weightValue() 1, 1, 2, 1
Print.wrongFormat() 1, 1, 2, 1
SoftName.compare() 1, 2, 3, 2
Student.getName() 1, 1, 2, 0
Student.getStudentNum() 1, 1, 2, 0
Student.setName() 1, 1, 2, 0
Student.setStudentNum() 1, 1, 2, 0
Student.Student() 1, 2, 2, 2
--------------------------------------------------------------------------------------------
Block Depth Statements
0 15
1 48
2 49
3 52
4 43
5 14
6 0
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
分析:
本题相对前两题的变化较大:考试以及实验的权重值发生变化,并在输入课的时候确定(包括实验课的实验次数),后续的输入成绩数量跟对应课程权重数量一致。对于计算成绩方式也发生变化,将成绩乘以对应权重并求和,最后输出Int类型数据忽略小数点。此题要求改变成绩类,从原来的继承关系转换成一个成绩类并改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。所以,最终我的成绩类设计为一个成绩类,有一个分项成绩类组合而成,分项成绩类包括权重ArrayList数组和成绩ArrayList数组(现在分析可知,该设计有取巧,设计与题目要求不是完全统一)。首先是对于输入课程的改进,在该正则表达式上加上实验次数(用?号表示0或1次),对于权重用*表示0至无数次,但是我将该正则表达式拆成3个,考察与前两次输入课一样,考试则加上两次权重,实验课于我描述的一致——"^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$"、"^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )((0.(0)+[1-9]|0.[1-9][0-9]*)( )(0.(0)+[1-9]|0.[1-9][0-9]*)$)"、"^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )([4-9])((( )(0.(0)+[1-9]|0.[1-9][0-9]*|1))*)(( )(0.(0)+[1-9]|0.[1-9][0-9]*))$"。对于输入课的数据处理顺序,先判断该课的名字是否已经输入(用containsKey方法在HashMap数组中查找),然后判断该课的课程性质和考核方式是否匹配,再判断考核方式于权重数量是否匹配,方式仍为判断该输入语句用split(" ")切割后的长度来判断,最后判断权重和是否为1,最后输入课程。对于判断权重和,因为精度问题,不要用double改用float,对于判断和是否为1,我用value>1.001||value<0.999代替为1(精度问题),也可把和数据转化为Int判断是否为1.对于输入成绩,跟以往相差不大。先判断是否有成绩重合,再判断改课是否存在,再判断输入的成绩数量与考核方式是否匹配。相对于之前,主要变化为判断考核方式与输入成绩的数量是否匹配:我的方式为判断成绩数量与所对应课程权重数组的长度是否相等。最后则是输出,再计算过程中,关于单成绩乘以权重,用float变量储存,最后求和,输出int类型,如果用double会卡测试点(原因未知)。
关于本题改变成绩类算法和前面相比有何不同:以我个人之见,本题将三个继承类整合成一个,成绩类由分项成绩类组合而成,这样做的好处就是:1. 更加自由化、可修改化,前两题的成绩类直接规定了不同考核方式的内容,如考试必须是平时成绩权重0.3、期末成绩必须是0.7,缺少可变性,而本算法可以按照需求不断地修改数据;2. 统一性,本题算法将所有情况整合成一个成绩类,对于输入成绩只需要一个流程,不用像前两题一样要根据考核方式不同调用不同的流程。3. 对于未来如果增加考核方式,也可有空间兼容,上一套算法规定只有3种考核方式,如若要增加,必须继续增加继承成绩类,和相应一套增加输入成绩信息的流程。但是也有所不足:1. 当查看加入的选课信息时,无法直观的辨明该选课信息的考核方式,只能通过查看其权重数量判断,但这输入取巧方式,对于信息的处理没有上一套算法直观。2. 很容易出现信息混淆情况,在输入成绩信息流程时,因为共用一套流程,易出现问题,如:学号 名字 课程名字 80 90,如果不处理,就容易出现信息处理错误,这就要求在设计的时候增加判断条件,相比之下没有上一套算法耐错性强。
好了,大作业分析结束啦,开始下一项~~
踩坑心得
1. 第六次大作业:
(1) 在输入课的过程中,没有考虑必须为“课程名字 必修/选修 考试/考察”这种格式,在类似于有特殊名词的数据处理中,要考虑是否必须为该特殊名词;
(2) java寻常的排序无法对中文起作用,需要导入特殊的中文包;
(3) 要注意题目要求,本次问题主要在于没有注意课程名字长度;
(4) 没有考虑重复课程信息要忽略的情况;
(5) 没有考虑重复成绩信息要忽略的情况;
2. 第七次大作业:
本题相较上题没什么改动,故没什么踩坑。(一遍过,实在想不到写什么)
3. 第八次大作业:
(1) 在运用double或者float类型数据,要考虑精度问题(如10个0.1值的double类型数据相加和为0.99999......,不等于1),在判断权重合时,如若判断其权重合是否等于1,会出现误差;
(3) 在计算单门成绩的时候,不能用double,而要用Float(至今不知道原因);
好了,踩坑心得到这里就结束了~~接下来就是最后的总结阶段了!!!!
主要困难及改进建议
困难:这段时间在学习里的困难主要在于javaFx的知识量过大,对于很多的方法只能通过网络查找的方式查找,对于javaFx的学习也在很肤浅的情况,如对于javaFx基础界面的构建、常规按钮的使用、以及图片的插入及移动等,对于动画的使用等几乎无涉猎。再来分析此系列大作业的困难,该系列的困难点在于如何给HashMap排序,以及如何让中文也参与排序,我解决的方式为将HashMap的key进行排序,从而达到排序的效果,但该方法较为繁琐,也可将HashMap转化为TreeMap,直接达到排序的效果;对于中文的排序,通过网络查找可知,可通过Collections.sort方法进行排序,但要对compare进行覆写,详情请看上文。
改进建议:关于这三次大作业的代码,由于核心类的设计思路已给出,故在设计上并没有遇到很大的困难。所以,我认为我的代码需要改进的方向主要在细节方向:迭代1和迭代2对于代码的复用率不高,导致出现很多的重复代码,个人认为可把如课程加入操作、成绩加入操作等单独打包成一个方法,即调即用,增强代码的复用度;对于数据判断处理,也可单独打包至一个判断方法,使代码的关联性更加分散,增加代码的延展性。
总结
本次博客已接近尾声了,我的java课程也接近尾声了,接下来对这段时间甚至这个学期的所学所得做一个总结!!!
首先,我们学习了Java的基本语法和面向对象编程的概念。我们了解了如何定义类和对象,并且学会了使用构造方法进行对象的初始化。我们还学习了Java的访问修饰符,如public、private和protected,以及其他一些关键字和语法规则。如何,我们学习了类的设计思路,了解到类设计的几大原则,以及设计类的注意事项。
在面向对象编程的部分,我们学习了Java的类和对象的概念,以及封装、继承和多态的原理和用法。我们了解了如何定义类的成员变量和方法,以及如何通过对象来访问这些成员。我们还学习了如何使用继承来创建派生类,并且了解了多态的概念和实现方式。此外,我们学习了Java的异常处理机制。我们了解了Java中的异常类和异常处理的语法,学会了如何捕获异常并进行相应的处理。我们还学习了如何使用try-catch来保护代码,以及如何抛出和捕获自定义异常。最后,我学习了可视化界面的设计——javaFx界面设计,了解到界面的构建、不同区块(button等)的作用,以及如何和现实存在如鼠标操作、键盘操作相关联。这一个学期的核心即为——面向对象程序设计,一个质量高、更简便、易维护、易拓展、效率高的设计思路。