OOP 第三阶段PTA题目集总结性BLOG
一、前言
题目集总结:
题目集7: 一道编程题,是程序菜单-4的平替,题量很少,仅此一道,难度的话,如果是认真分析自主完成了程序菜单-4的话,只需在原代码上进行改进完善就好,甚至由于菜单-5的异常情况相对于菜单-4来说更少,实际上是更容易了(毕竟从从4—>5肯定是要比从1—>4要简单多的^ ^),考查的依然是复杂的类的设计以及正则表达式的正确使用和生活实际问题的分析进而转为程序设计。
题目集8: 也是一道编程题,不过菜单系列的设计终于完结了,这次变成了课程成绩的分析的程序设计,与菜单系列考查的内容大致相同,不过在这个系列,老师着重强调了继承和组合两个关系的使用与区别,由于是成绩-1,还没开始迭代,难度不大,大部分同学能顺利AK。
题目集9: 一道编程题,老师一改往日风格,竟然不是成绩系列的迭代,而是考查语法(map, set)的使用。难度适中,关键在于正则表达式以及字符替换的使用。
题目集10: 一共四道编程题,两道语法题加成绩-2再加一道考查继承与多态的题目,题量适中,总体难度不大。
题目集11: 一共五道编程题,类型与前一次类似,语法题加成绩系列迭代,题量稍稍变多,但难度依旧不大,总体能够接受。
题目集感悟:
1) 这些题目集主要是编程题,涵盖了不同的主题和难度级别。从菜单设计到成绩分析,再到语法和继承多态,这些题目考察了不同的编程概念和技能。
首先,菜单系列题目考察了复杂类的设计以及正则表达式的正确使用。这要求我们能够合理地组织代码结构,设计类和函数,并运用正则表达式来处理输入和匹配模式。此外,菜单-5的题目相对于菜单-4来说更容易,因为它的异常情况更少,我们可以在原有代码的基础上进行改进和完善。
接下来,课程成绩分析的题目要求我们在菜单系列的基础上进一步应用继承和组合的关系。这意味着我们需要理解这两种关系的使用和区别,并能够合理地设计和组织类的结构。这是一个相对简单的题目,大多数同学应该可以轻松完成。
在题目集9中,考查了语法(map, set)的使用,以及正则表达式和字符替换的运用。这需要我们熟悉map和set这两种数据结构的基本操作,同时能够正确运用正则表达式进行字符串匹配和替换。
而在题目集10和题目集11中,涉及到了更多的题目数量和题目类型,包括语法题、成绩迭代和继承多态。这要求我们能够综合运用前面学过的知识,灵活应用编程技巧来解决问题。总体难度适中,需要一定的编程基础和综合能力。
通过完成这些题目,我们可以提升自己的编程能力和解决问题的能力。同时,还能够加深对不同概念和技术的理解和应用。编程是一个不断学习和提升的过程,通过解决各种类型的题目,我们可以不断锻炼自己的思维和编码能力,为以后的编程工作打下坚实的基础。
2) 通过这些编程题的练习,我深刻地认识到编程能力的提高需要不断地练习和学习。从基础语法和算法的应用到高级容器和Java库类的使用,再到类的设计和封装性的运用,这些题目涵盖了编程的多个方面,每个练习都让我从中学到了新的知识和技能。
在练习过程中,我也意识到了编程中的一些重要概念,如封装、聚合关系等。对于类的设计和封装性的运用,我也开始慢慢理解和掌握。同时,我也发现了自己在某些方面的不足和需要进一步提高的地方,比如对于复杂类的设计,我需要更加深入地了解和掌握相关知识。
除了学习和练习,我还需要不断地思考和总结,将所学所练习到的知识和技能整合起来,形成自己的思维模型和编程风格。通过不断地思考和总结,我相信我的编程能力将会得到进一步的提高。
3) 由于处于Java学习的最后一个阶段,老师也从之前一直强调的类设计,设计模式等等一些深层次的知识回归到基础语法与数据结构的教学,题目集的题目设计也相应发生变化,我觉得这样的教学方法是非常好的,行之有效,个人感觉目前自己的水平有了很大的提升,不再是之前那个只会面向过程甚至是面向样例编程的初学者了。
二、设计和分析
OOP训练集08
7-1 课程成绩统计程序-1
题目:
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
String requiredCourse = "\\S{1,10} 必修 考试";
String optionalCourseExam = "\\S{1,10} 选修 考试";
String optionalCourseInv = "\\S{1,10} 选修 考察";
String CourseWrong = "\\S{1,10} 必修 考察";
String ScoreExam = "\\d{8} \\S{1,10} \\S{1,10} ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)";
String ScoreInv = "\\d{8} \\S{1,10} \\S{1,10} ([0-9]|[1-9][0-9]|100)";
ArrayList<Course> courses = new ArrayList<>(); // 存储所有课程
ArrayList<Curricula> curriculaVariables = new ArrayList<>(); // 存储所有选课
ArrayList<Class> classes = new ArrayList<>(); // 存储所有班级
ArrayList<Student> students = new ArrayList<>(); // 存储所有学生
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
while (!input.equals("end")) {
boolean courseIsExist = false;
boolean modeIsMatched = false;
boolean classIsExist = false;
boolean studentIsExist = false;
boolean curriculaVariableIsExist = false;
String[] strings = input.split("\\s+");
if (input.matches(requiredCourse) || input.matches(optionalCourseExam) || input.matches(optionalCourseInv)) {
if (courses.isEmpty()) {
Course course = new Course(strings[0], strings[1], strings[2]);
courses.add(course);
} else {
boolean isContain = false;
for (Course course : courses) {
if (course.getName().equals(strings[0])) {
isContain = true;
break;
}
}
if (!isContain) {
Course course = new Course(strings[0], strings[1], strings[2]);
courses.add(course);
}
}
} else if (input.matches(ScoreExam) || input.matches(ScoreInv)) {
String classNum = strings[0].substring(0,6);
String studentNum = strings[0];
String studentName = strings[1];
String courseName = strings[2];
Course course = new Course();
if (!classes.isEmpty()) {
for (Class classTmp : classes) {
if (classTmp.getNum().equals(classNum)) {
for (Student studentTmp : classTmp.getStudents()) {
if (studentTmp.getName().equals(studentName)) {
studentIsExist = true;
break;
}
}
classIsExist = true;
break;
}
}
}
if (!classIsExist) {
Class classNew = new Class(classNum);
Student student = new Student(studentNum, studentName);
students.add(student);
classNew.getStudents().add(student);
classes.add(classNew);
} else {
if (!studentIsExist) {
Student student = new Student(studentNum, studentName);
students.add(student);
for (int i = 0; i < classes.size(); i ++) {
if (classes.get(i).getNum().equals(classNum)) {
classes.get(i).getStudents().add(student);
break;
}
}
}
}
if (input.matches(ScoreExam)) {
int scoreDaily = Integer.parseInt(strings[3]);
int socreFinal = Integer.parseInt(strings[4]);
for (int i = 0; i < courses.size(); i ++) {
if (courses.get(i).getName().equals(courseName)) {
if (courses.get(i).getMode().equals("考试")) modeIsMatched = true;
course = courses.get(i);
courseIsExist = true;
break;
}
}
if (!courseIsExist) System.out.println(courseName + " does not exist");
else {
if (!modeIsMatched) System.out.println(studentNum + " " + studentName + " : access mode mismatch");
else {
for (Curricula curriculaVariableTmp : curriculaVariables) {
if (curriculaVariableTmp.getStudent().getNum().equals(studentNum) && curriculaVariableTmp.getCourse().getName().equals(courseName)) {
curriculaVariableIsExist = true;
break;
}
}
if (!curriculaVariableIsExist) {
Score score = new ExamScore(scoreDaily, socreFinal);
Student student = new Student(studentNum, studentName);
Curricula curriculaVariable = new Curricula(student, score, course);
curriculaVariables.add(curriculaVariable);
}
}
}
} else if (input.matches(ScoreInv)) {
int socreFinal = Integer.parseInt(strings[3]);
for (int i = 0; i < courses.size(); i ++) {
if (courses.get(i).getName().equals(courseName)) {
if (courses.get(i).getMode().equals("考察")) modeIsMatched = true;
course = courses.get(i);
courseIsExist = true;
break;
}
}
if (!courseIsExist) System.out.println(courseName + " does not exist");
else {
if (!modeIsMatched) System.out.println(studentNum + " " + studentName + " : access mode mismatch");
else {
for (Curricula curriculaVariableTmp : curriculaVariables) {
if (curriculaVariableTmp.getStudent().getNum().equals(studentNum) && curriculaVariableTmp.getCourse().getName().equals(courseName)) {
curriculaVariableIsExist = true;
break;
}
}
if (!curriculaVariableIsExist) {
Score score = new InvScore(socreFinal);
Student student = new Student(studentNum, studentName);
Curricula curriculaVariable = new Curricula(student, score, course);
curriculaVariables.add(curriculaVariable);
}
}
}
}
} else if (input.matches(CourseWrong)) System.out.println(strings[0] + " : course type & access mode mismatch");
else System.out.println("wrong format");
input = scanner.nextLine();
}
Collections.sort(students);
for (Student student : students) {
boolean hasScore = false;
int sumScore = 0;
int courseNum = 0;
for (Curricula curriculaVariable : curriculaVariables) {
if (student.getNum().equals(curriculaVariable.getStudent().getNum())) {
hasScore = true;
if (curriculaVariable.getScore() instanceof ExamScore) {
sumScore = sumScore + ((ExamScore) curriculaVariable.getScore()).getFinalFinalScore();
courseNum ++;
} else if (curriculaVariable.getScore() instanceof InvScore) {
sumScore = sumScore + ((InvScore) curriculaVariable.getScore()).getFFScore();
courseNum ++;
}
}
}
if (hasScore) {
int studentAverScore = sumScore / courseNum;
System.out.println(student.getNum() + " " + student.getName() + " " + studentAverScore);
} else System.out.println(student.getNum() + " " + student.getName() + " did not take any exams");
}
Comparator<Course> comparator = new Comparator<Course>() {
Collator collator = Collator.getInstance(Locale.CHINA);
@Override
public int compare(Course o1, Course o2) {
return collator.compare(o1.getName(), o2.getName());
}
};
Collections.sort(courses, comparator);
for (Course course : courses) {
boolean hasScore = false;
int sumDailyScore = 0;
int sumFinalScore = 0;
int sumFinalFinalScore = 0;
int studentNum = 0;
if (course.getMode().equals("考察")) {
for (Curricula curriculaVariable : curriculaVariables) {
if (course.getName().equals(curriculaVariable.getCourse().getName())) {
hasScore = true;
sumFinalScore = sumFinalScore + ((InvScore) curriculaVariable.getScore()).getFFScore();
studentNum ++;
}
}
if (hasScore) {
sumFinalFinalScore = sumFinalScore;
int courseAverFinalScore = sumFinalFinalScore / studentNum;
System.out.println(course.getName() + " " + courseAverFinalScore + " " + courseAverFinalScore);
} else System.out.println(course.getName() + " has no grades yet");
} else if (course.getMode().equals("考试")) {
for (Curricula curriculaVariable : curriculaVariables) {
if (course.getName().equals(curriculaVariable.getCourse().getName())) {
hasScore = true;
sumDailyScore = sumDailyScore + ((ExamScore) curriculaVariable.getScore()).getDailyScore();
sumFinalScore = sumFinalScore + ((ExamScore) curriculaVariable.getScore()).getFinalScore();
sumFinalFinalScore = sumFinalFinalScore + ((ExamScore) curriculaVariable.getScore()).getFinalFinalScore();
studentNum ++;
}
}
if (hasScore) {
int courseAverDailyScore = sumDailyScore / studentNum;
int courseAverFinalScore = sumFinalScore / studentNum;
int courseAverScore = sumFinalFinalScore / studentNum;
System.out.println(course.getName() + " " + courseAverDailyScore + " " + courseAverFinalScore + " " + courseAverScore);
} else System.out.println(course.getName() + " has no grades yet");
}
}
Collections.sort(classes);
for (Class classTmp : classes) {
boolean hasScore = false;
int sumScore = 0;
int num = 0;
for (Curricula curriculaVariable : curriculaVariables) {
String classeNum = curriculaVariable.getStudent().getNum().substring(0,6);
if (classTmp.getNum().equals(classeNum)) {
hasScore = true;
if (curriculaVariable.getScore() instanceof ExamScore) {
sumScore = sumScore + ((ExamScore) curriculaVariable.getScore()).getFinalFinalScore();
num ++;
} else if (curriculaVariable.getScore() instanceof InvScore) {
sumScore = sumScore + ((InvScore) curriculaVariable.getScore()).getFFScore();
num ++;
}
}
}
if (hasScore) {
int averScore = sumScore / num;
System.out.println(classTmp.getNum() + " " + averScore);
} else System.out.println(classTmp.getNum() + " has no grades yet");
}
}
}
class Student implements Comparable<Student> {
private String num;
private String name;
Student() {
}
Student(String num, String name) {
this.num = num;
this.name = name;
}
public String getNum() {
return num;
}
public String getName() {
return name;
}
@Override
public int compareTo(Student o) {
return this.getNum().compareTo(o.getNum());
}
}
class Class implements Comparable<Class> {
private String num;
private ArrayList<Student> students;
Class() {
}
Class(String num) {
this.num = num;
students = new ArrayList<>();
}
public String getNum() {
return num;
}
public ArrayList<Student> getStudents() {
return students;
}
@Override
public int compareTo(Class o) {
return this.getNum().compareTo(o.getNum());
}
}
class Course {
private String name;
private String type;
private String mode;
Course() {
}
public Course(String name, String type, String mode) {
this.name = name;
this.type = type;
this.mode = mode;
}
public String getName() {
return name;
}
public String getMode() {
return mode;
}
}
abstract class Score {
protected int dailyScore;
protected int finalScore;
Score() {
}
}
class ExamScore extends Score {
private int dailyScore;
private int finalScore;
ExamScore() {
}
public ExamScore(int dailyScore, int finalScore) {
this.dailyScore = dailyScore;
this.finalScore = finalScore;
}
public int getDailyScore() {
return dailyScore;
}
public int getFinalScore() {
return finalScore;
}
public int getFinalFinalScore() {
return (int)(getDailyScore() * 0.3 + getFinalScore() * 0.7);
}
}
class InvScore extends Score {
private int finalScore;
InvScore() {
}
public InvScore(int finalScore) {
this.finalScore = finalScore;
}
public int getFFScore() {
return this.finalScore;
}
}
class Curricula {
private Student student;
private Course course;
private Score score;
Curricula() {
}
public Curricula(Student student, Score score, Course course) {
this.student = student;
this.score = score;
this.course = course;
}
public Student getStudent() {
return student;
}
public Score getScore() {
return score;
}
public Course getCourse() {
return course;
}
}
代码质量的分析报告:
1.可读性
代码使用了具有描述性的变量和方法命名,使得代码易于理解。
适当添加了注释,帮助读者理解代码的作用和逻辑。
代码块之间使用空行和缩进进行了分隔,增加了代码的可读性。
2.可维护性
代码结构清晰,采用了面向对象的设计模式,将功能模块划分为不同的类,提高了代码的可维护性。
使用了合适的数据结构(如ArrayList)来存储和管理数据,便于扩展和修改。
使用了集合类提供的排序方法和比较器,简化了代码逻辑,提高了可维护性。
3.可测试性
代码中的大部分功能都封装在类的方法中,易于单独测试和验证。
使用了Scanner类来读取用户输入,方便测试不同的输入场景。
4.性能
在课程成绩计算部分,使用了ArrayList来存储和处理数据,适合小规模数据集。
由于代码量较少且没有复杂的计算或循环逻辑,整体性能良好。
5.可靠性
代码中使用了适当的异常处理,例如在解析用户输入时,会检查输入格式是否匹配,避免潜在的异常情况。
对于一些不匹配的输入格式或错误情况,会输出相应的错误信息,提高了代码的可靠性。
6.安全性
代码在处理用户输入时,使用了正则表达式进行格式验证,可以有效防止恶意输入和注入攻击。
在处理成绩计算时,对于无效的课程和访问模式不匹配的情况,会输出相应的警告信息,确保计算结果的准确性和安全性。
7.可扩展性
代码采用了面向对象的设计,使用了类和对象进行模块化开发,易于扩展和修改。
可以通过添加新的类和方法来支持更多的功能需求,而不需要大规模改动现有的代码。
类图:

解释和心得:
代码解释:
主要类和数据结构:
Student类:表示学生对象,包含学号和姓名。
Class类:表示班级对象,包含班级编号和学生列表。
Course类:表示课程对象,包含课程名称、类型和考试模式。
Score抽象类:表示成绩对象的基类,包含日常成绩和期末成绩。
ExamScore类:表示考试成绩对象,继承自Score类,包含日常成绩和期末成绩,并提供计算最终成绩的方法。
InvScore类:表示考察成绩对象,继承自Score类,只包含期末成绩。
Curricula类:表示学生选课和成绩对象,包含学生、课程和成绩信息。
主要数据存储结构:
ArrayList< Course > courses:存储所有课程对象。
ArrayList< Curricula > curriculaVariables:存储所有选课和成绩对象。
ArrayList< Class > classes:存储所有班级对象。
ArrayList< Student > students:存储所有学生对象。
主要流程:
通过命令行输入逐行读取数据,并对输入的数据进行解析和处理。
根据输入的数据类型(必修考试课程、选修考试课程、选修考察课程、考试成绩、考察成绩等),将数据存储到对应的数据结构中。
对学生和课程数据进行排序,并根据要求进行统计和计算,输出结果。
类的设计和功能:
Main 类:
main 方法是程序的入口点,负责读取用户输入和处理课程和成绩数据。
它使用正则表达式来匹配用户输入的不同模式,并根据模式来创建课程、学生、班级和成绩对象。
它还对数据进行排序并输出相应的结果。
Student 类:
Student 类表示学生对象,具有学号和姓名两个属性。
它实现了 Comparable 接口,用于在学生对象之间进行比较和排序。
Class 类:
Class 类表示班级对象,具有班级编号和学生列表两个属性。
它实现了 Comparable 接口,用于在班级对象之间进行比较和排序。
它提供了方法来获取班级编号和学生列表。
Course 类:
Course 类表示课程对象,具有课程名称、类型和模式三个属性。
它提供了方法来获取课程名称和模式。
Score 抽象类:
Score 类是一个抽象基类,表示成绩对象。
它定义了两个子类需要实现的抽象方法,用于计算最终得分。
ExamScore 类:
ExamScore 类是 Score 类的子类,表示考试成绩对象。
它具有每日得分和期末得分两个属性。
它实现了父类中定义的抽象方法,计算并返回最终得分。
InvScore 类:
InvScore 类是 Score 类的子类,表示考察成绩对象。
它具有期末得分属性。
它实现了父类中定义的抽象方法,计算并返回最终得分。
Curricula 类:
Curricula 类表示课程安排对象,包含学生、成绩和课程三个属性。
它提供了方法来获取学生、成绩和课程对象。
在 Main 类的 main 方法中,首先使用正则表达式来匹配用户输入的不同模式,根据模式创建相应的对象。然后,根据成绩类型(考试或考察)计算最终得分,并将相应的数据存储在 students、curriculaVariables 和 classes 列表中。最后,对数据进行排序,并根据题目要求输出相应的结果。
心得:
在我看来,无非就是换了马甲的菜单系列,何况还是第一代,有了菜单系列的经验之后,写起来还算得心应手,没有遇到什么坑。
OOP训练集11
7-2 课程成绩统计程序-3
题目:
课程成绩统计程序-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 matchjava : 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.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
String requiredCourse = "\\S{1,10} 必修 考试(\\s+(-?\\d+)(.\\d+|\\d+)?)(\\s+(-?\\d+)(.\\d+|\\d+)?)";
String optionalCourseExam = "\\S{1,10} 选修 考试(\\s+(-?\\d+)(.\\d+|\\d+)?)(\\s+(-?\\d+)(.\\d+|\\d+)?)";
String optionalCourseInv = "\\S{1,10} 选修 考察";
String experimentCourse = "\\S{1,10} 实验 实验 [4-9](\\s+(-?\\d+)(.\\d+|\\d+)?)+";
String CourseWrong1 = "\\S{1,10} 必修 考察";
String CourseWrong2 = "\\S{1,10} 必修 实验 [4-9](\\s+(0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String CourseWrong21 = "\\S{1,10} 必修 实验";
String CourseWrong3 = "\\S{1,10} 选修 实验 [4-9](\\s+(0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String CourseWrong31 = "\\S{1,10} 选修 实验";
String CourseWrong32 = "\\S{1,10} 选修 实验( (0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String CourseWrong4 = "\\S{1,10} 实验 考试( (0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String CourseWrong41 = "\\S{1,10} 实验 考试 [4-9](\\s+(0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String CourseWrong5 = "\\S{1,10} 实验 考察";
String CourseWrong51 = "\\S{1,10} 实验 考察 [4-9](\\s+(0(?:\\.\\d+)?|1(?:\\.0+)?))+";
String ScoreExperiment = "\\d{8} \\S{1,10} \\S{1,10}(\\s+(?:[0-9]{1,2}|100))+";
String ScoreExam = "\\d{8} \\S{1,10} \\S{1,10} ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)";
String ScoreInv = "\\d{8} \\S{1,10} \\S{1,10} ([0-9]|[1-9][0-9]|100)";
ArrayList<Course> courses = new ArrayList<>(); // 存储所有课程
ArrayList<Curricula> curriculaVariables = new ArrayList<>(); // 存储所有选课
ArrayList<Class> classes = new ArrayList<>(); // 存储所有班级
ArrayList<Student> students = new ArrayList<>(); // 存储所有学生
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
while (!input.equals("end")) {
boolean courseIsExist = false;
boolean modeIsMatched = false;
boolean classIsExist = false;
boolean studentIsExist = false;
boolean curriculaVariableIsExist = false;
String[] strings = input.split("\\s+");
if (input.matches(requiredCourse) || input.matches(optionalCourseExam) || input.matches(optionalCourseInv) || input.matches(experimentCourse)) {
boolean isContain = false;
for (Course course : courses) {
if (course.getName().equals(strings[0])) {
isContain = true;
break;
}
}
if (!isContain) {
Course course = new Course(strings[0], strings[1], strings[2]);
if (input.matches(optionalCourseInv)) {
course.getWeights().add(1.0);
courses.add(course);
}
else if (input.matches(requiredCourse) || input.matches(optionalCourseExam)) {
if (Math.abs(Double.parseDouble(strings[3]) + Double.parseDouble(strings[4]) - 1) > 0.000001)
System.out.println(strings[0] + " : weight value error");
else {
course.getWeights().add(Double.parseDouble(strings[3]));
course.getWeights().add(Double.parseDouble(strings[4]));
courses.add(course);
}
} else {
if (Integer.parseInt(strings[3]) > 9 || Integer.parseInt(strings[3]) < 4) System.out.println(strings[0] + " : course type & access mode mismatch");
else {
if (strings.length != 4 + Integer.parseInt(strings[3])) System.out.println(strings[0] + " : number of scores does not match");
else {
double sum = 0;
for (int i = 4; i < strings.length; i++) sum += Double.parseDouble(strings[i]);
if (Math.abs(sum - 1) > 0.000001) System.out.println(strings[0] + " : weight value error");
else {
for (int i = 4; i < strings.length; i++) {
course.getWeights().add(Double.parseDouble(strings[i]));
}
courses.add(course);
}
}
}
}
}
} else if (input.matches(ScoreExam) || input.matches(ScoreInv) || input.matches(ScoreExperiment)) {
String classNum = strings[0].substring(0,6);
String studentNum = strings[0];
String studentName = strings[1];
String courseName = strings[2];
ArrayList<Double> weights = null;
Course course = new Course();
if (!classes.isEmpty()) {
for (Class classTmp : classes) {
if (classTmp.getNum().equals(classNum)) {
for (Student studentTmp : classTmp.getStudents()) {
if (studentTmp.getName().equals(studentName)) {
studentIsExist = true;
break;
}
}
classIsExist = true;
break;
}
}
}
if (!classIsExist) {
Class classNew = new Class(classNum);
Student student = new Student(studentNum, studentName);
students.add(student);
classNew.getStudents().add(student);
classes.add(classNew);
} else {
if (!studentIsExist) {
Student student = new Student(studentNum, studentName);
students.add(student);
for (int i = 0; i < classes.size(); i ++) {
if (classes.get(i).getNum().equals(classNum)) {
classes.get(i).getStudents().add(student);
break;
}
}
}
}
if (input.matches(ScoreExam)) {
int scoreDaily = Integer.parseInt(strings[3]);
int socreFinal = Integer.parseInt(strings[4]);
for (int i = 0; i < courses.size(); i ++) {
if (courses.get(i).getName().equals(courseName)) {
if (courses.get(i).getMode().equals("考试")) modeIsMatched = true;
course = courses.get(i);
weights = course.getWeights();
courseIsExist = true;
break;
}
}
if (!courseIsExist) System.out.println(courseName + " does not exist");
else {
if (!modeIsMatched) System.out.println(studentNum + " " + studentName + " : access mode mismatch");
else {
for (Curricula curriculaVariableTmp : curriculaVariables) {
if (curriculaVariableTmp.getStudent().getNum().equals(studentNum) && curriculaVariableTmp.getCourse().getName().equals(courseName)) {
curriculaVariableIsExist = true;
break;
}
}
if (!curriculaVariableIsExist) {
ExamScore examScore = new ExamScore(scoreDaily, weights.get(0), socreFinal, weights.get(1));
Score score = new Score(examScore);
Student student = new Student(studentNum, studentName);
Curricula curriculaVariable = new Curricula(student, score, course);
curriculaVariables.add(curriculaVariable);
}
}
}
} else if (input.matches(ScoreInv)) {
int socreFinal = Integer.parseInt(strings[3]);
for (int i = 0; i < courses.size(); i ++) {
if (courses.get(i).getName().equals(courseName)) {
if (courses.get(i).getMode().equals("考察")) modeIsMatched = true;
course = courses.get(i);
courseIsExist = true;
break;
}
}
if (!courseIsExist) System.out.println(courseName + " does not exist");
else {
if (!modeIsMatched) System.out.println(studentNum + " " + studentName + " : access mode mismatch");
else {
for (Curricula curriculaVariableTmp : curriculaVariables) {
if (curriculaVariableTmp.getStudent().getNum().equals(studentNum) && curriculaVariableTmp.getCourse().getName().equals(courseName)) {
curriculaVariableIsExist = true;
break;
}
}
if (!curriculaVariableIsExist) {
InvScore invScore = new InvScore(socreFinal);
Score score = new Score(invScore);
Student student = new Student(studentNum, studentName);
Curricula curriculaVariable = new Curricula(student, score, course);
curriculaVariables.add(curriculaVariable);
}
}
}
} else if (input.matches(ScoreExperiment) && strings.length > 5) {
for (int i = 0; i < courses.size(); i++) {
if (courses.get(i).getName().equals(courseName)) {
course = courses.get(i);
weights = course.getWeights();
courseIsExist = true;
break;
}
}
if (!courseIsExist) System.out.println(courseName + " does not exist");
else {
if (weights.size() != strings.length - 3) System.out.println(studentNum + " " + studentName + " : access mode mismatch");
else {
ExperimentScore experimentScore = new ExperimentScore();
for (int i = 3, j = 0; i < 3 + weights.size(); i ++) {
DivideScore divideScore = new DivideScore(Integer.parseInt(strings[i]), weights.get(j));
experimentScore.getDivideScores().add(divideScore);
j ++;
}
for (Curricula curriculaVariableTmp : curriculaVariables) {
if (curriculaVariableTmp.getStudent().getNum().equals(studentNum) && curriculaVariableTmp.getCourse().getName().equals(courseName)) {
curriculaVariableIsExist = true;
break;
}
}
if (!curriculaVariableIsExist) {
Score score = new Score(experimentScore);
Student student = new Student(studentNum, studentName);
Curricula curriculaVariable = new Curricula(student, score, course);
curriculaVariables.add(curriculaVariable);
}
}
}
}
} else if (input.matches(CourseWrong1) || input.matches(CourseWrong2) || input.matches(CourseWrong3) || input.matches(CourseWrong4) || input.matches(CourseWrong5) ||
input.matches(CourseWrong21) || input.matches(CourseWrong31) || input.matches(CourseWrong32) || input.matches(CourseWrong41) || input.matches(CourseWrong51)) System.out.println(strings[0] + " : course type & access mode mismatch");
else System.out.println("wrong format");
input = scanner.nextLine();
}
output(students, courses, classes, curriculaVariables);
}
public static void output(ArrayList<Student> students, ArrayList<Course> courses, ArrayList<Class> classes, ArrayList<Curricula> curriculaVariables) {
Collections.sort(students);
for (Student student : students) {
boolean hasScore = false;
int sumScore = 0;
int courseNum = 0;
for (Curricula curriculaVariable : curriculaVariables) {
if (student.getNum().equals(curriculaVariable.getStudent().getNum())) {
hasScore = true;
if (curriculaVariable.getScore().getExamScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExamFinalScore();
courseNum ++;
} else if (curriculaVariable.getScore().getInvScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getInvFinalScore();
courseNum ++;
} else if (curriculaVariable.getScore().getExperimentScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExperimentFinalScore();
courseNum ++;
}
}
}
if (hasScore) {
int studentAverScore = sumScore / courseNum;
System.out.println(student.getNum() + " " + student.getName() + " " + studentAverScore);
} else System.out.println(student.getNum() + " " + student.getName() + " did not take any exams");
}
Comparator<Course> comparator = new Comparator<Course>() {
Collator collator = Collator.getInstance(Locale.CHINA);
@Override
public int compare(Course o1, Course o2) {
return collator.compare(o1.getName(), o2.getName());
}
};
Collections.sort(courses, comparator);
for (Course course : courses) {
boolean hasScore = false;
int sumScore = 0;
int courseNum = 0;
for (Curricula curriculaVariable : curriculaVariables) {
if (course.getName().equals(curriculaVariable.getCourse().getName())) {
hasScore = true;
if (curriculaVariable.getScore().getExamScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExamFinalScore();
courseNum ++;
} else if (curriculaVariable.getScore().getInvScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getInvFinalScore();
courseNum ++;
} else if (curriculaVariable.getScore().getExperimentScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExperimentFinalScore();
courseNum ++;
}
}
}
if (hasScore) {
int studentAverScore = sumScore / courseNum;
System.out.println(course.getName() + " " + studentAverScore);
} else System.out.println(course.getName() + " has no grades yet");
}
Collections.sort(classes);
for (Class classTmp : classes) {
boolean hasScore = false;
int sumScore = 0;
int num = 0;
for (Curricula curriculaVariable : curriculaVariables) {
String classeNum = curriculaVariable.getStudent().getNum().substring(0,6);
if (classTmp.getNum().equals(classeNum)) {
hasScore = true;
if (curriculaVariable.getScore().getExamScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExamFinalScore();
num ++;
} else if (curriculaVariable.getScore().getInvScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getInvFinalScore();
num ++;
} else if (curriculaVariable.getScore().getExperimentScore() != null) {
sumScore = sumScore + curriculaVariable.getScore().getExperimentFinalScore();
num ++;
}
}
}
if (hasScore) {
int averScore = sumScore / num;
System.out.println(classTmp.getNum() + " " + averScore);
} else System.out.println(classTmp.getNum() + " has no grades yet");
}
}
}
class Student implements Comparable<Student> {
private String num;
private String name;
Student() {
}
Student(String num, String name) {
this.num = num;
this.name = name;
}
public String getNum() {
return num;
}
public String getName() {
return name;
}
@Override
public int compareTo(Student o) {
return this.getNum().compareTo(o.getNum());
}
}
class Class implements Comparable<Class> {
private String num;
private ArrayList<Student> students;
Class() {
}
Class(String num) {
this.num = num;
students = new ArrayList<>();
}
public String getNum() {
return num;
}
public ArrayList<Student> getStudents() {
return students;
}
@Override
public int compareTo(Class o) {
return this.getNum().compareTo(o.getNum());
}
}
class Course {
private String name;
private String type;
private String mode;
private ArrayList<Double> weights;
Course() {
this.weights = new ArrayList<>();
}
public Course(String name, String type, String mode) {
this.name = name;
this.type = type;
this.mode = mode;
this.weights = new ArrayList<>();
}
public ArrayList<Double> getWeights() {
return weights;
}
public void setWeights(ArrayList<Double> weights) {
this.weights = weights;
}
public String getName() {
return name;
}
public String getMode() {
return mode;
}
}
class Score {
private ExperimentScore experimentScore;
private ExamScore examScore;
private InvScore invScore;
Score() {
}
Score(ExperimentScore experimentScore) {
this.experimentScore = experimentScore;
this.examScore = null;
this.invScore = null;
}
Score(ExamScore examScore) {
this.experimentScore = null;
this.examScore = examScore;
this.invScore = null;
}
Score(InvScore invScore) {
this.experimentScore = null;
this.examScore = null;
this.invScore = invScore;
}
public ExperimentScore getExperimentScore() {
return experimentScore;
}
public ExamScore getExamScore() {
return examScore;
}
public InvScore getInvScore() {
return invScore;
}
public int getExperimentFinalScore() {
return experimentScore.getFFScore();
}
public int getExamFinalScore() {
return examScore.getFFScore();
}
public int getInvFinalScore() {
return invScore.getFFScore();
}
}
class ExperimentScore extends Score {
private ArrayList<DivideScore> divideScores;
ExperimentScore() {
divideScores = new ArrayList<>();
}
public void setDivideScores(ArrayList<DivideScore> divideScores) {
this.divideScores = divideScores;
}
public ArrayList<DivideScore> getDivideScores() {
return divideScores;
}
public int getFFScore() {
float sumScore = 0;
for (DivideScore divideScore : divideScores) sumScore = sumScore + divideScore.getOneDivSco();
return (int) sumScore;
}
}
class ExamScore extends Score {
private DivideScore dailyDivSco;
private DivideScore finalDivSco;
ExamScore() {
}
public ExamScore(int dailyValue, double dailyWeight, int finalValue, double finalWeight) {
this.dailyDivSco = new DivideScore(dailyValue, dailyWeight);
this.finalDivSco = new DivideScore(finalValue, finalWeight);
}
public int getFFScore() {
return (int) (dailyDivSco.getOneDivSco() + finalDivSco.getOneDivSco());
}
}
class InvScore extends Score {
private DivideScore finalDivSco;
InvScore() {
}
InvScore(int finalScore) {
int value = finalScore;
double weight = 1;
this.finalDivSco = new DivideScore(value, weight);
}
public int getFFScore() {
return (int) (finalDivSco.getOneDivSco());
}
}
class DivideScore {
private int value;
private double weight;
public DivideScore(int value, double weight) {
this.value = value;
this.weight = weight;
}
public float getOneDivSco() {
return (float) (value * weight);
}
}
class Curricula {
private Student student;
private Course course;
private Score score;
Curricula() {
}
public Curricula(Student student, Score score, Course course) {
this.student = student;
this.score = score;
this.course = course;
}
public Student getStudent() {
return student;
}
public Score getScore() {
return score;
}
public Course getCourse() {
return course;
}
}
代码质量的分析报告:
1.可读性
代码整体结构清晰,使用了合适的命名,容易理解代码的功能和含义。
代码使用了适当的注释,提供了一些解释和指导,帮助读者理解代码的目的和实现。
代码块之间使用空行进行分隔,增强了可读性。
2.可维护性
代码模块化良好,各个功能通过类和方法进行封装,提高了代码的可维护性。
使用了合适的数据结构(ArrayList、Scanner等),使得代码易于理解和修改。
使用了面向对象的设计,将相关的数据和操作封装在类中,降低了代码的耦合度。
3.可测试性
代码中的大部分功能通过方法进行封装,易于进行单元测试。
方法之间的逻辑相对独立,可以针对每个方法编写测试用例进行测试。
4.性能
代码没有明显的性能问题,使用了合适的数据结构和算法。
通过使用ArrayList存储数据,可以提高数据的访问和操作效率。
5.可靠性
代码中使用了异常处理机制,对可能出现的异常情况进行了处理,增加了代码的可靠性。
使用了一些条件判断和错误输出,可以及时发现错误,并给出相应的提示。
6.安全性
代码中没有直接涉及到安全问题的处理,需要根据具体场景和需求增加相应的安全措施。
7.可扩展性
代码使用了面向对象的设计,将不同功能封装在不同的类中,易于扩展和修改。
可以根据需要添加新的类和方法,扩展代码的功能。
类图:

解释和心得:
代码解释:
1)
代码首先定义了一些正则表达式,用于匹配输入的不同格式的课程和成绩信息。
接下来,代码创建了四个ArrayList对象,分别用于存储所有的课程、选课、班级和学生的信息。
然后,代码通过Scanner对象获取用户输入的信息,并在一个循环中处理输入,直到用户输入"end"为止。
在处理输入时,代码根据正则表达式匹配输入的信息,判断输入的信息类型(课程信息、成绩信息、错误格式等),并进行相应的处理。
对于课程信息,代码会检查该课程是否已经存在,如果不存在则创建一个新的课程对象并添加到课程列表中。根据不同的课程类型和访问模式,设置相应的权重。
对于成绩信息,代码会检查班级和学生是否存在,如果不存在则创建新的班级和学生对象,并将学生添加到班级和学生列表中。然后,根据不同的成绩类型和访问模式,创建相应的成绩对象,并将学生、成绩和课程信息添加到选课列表中。
最后,代码调用output函数,对学生和课程列表进行排序,并根据成绩计算学生的平均成绩和课程的平均成绩,并输出结果。
总体而言,这段代码实现了一个简单的成绩管理系统,可以通过输入课程和成绩信息来管理和计算学生的成绩。它使用了面向对象的设计思想,通过类的组织和关联来实现对不同实体的管理,并通过正则表达式匹配和条件判断来处理不同类型的输入信息。
2)
主函数:
主函数通过输入从用户获取输入的字符串,并根据输入的字符串进行逻辑处理和计算。
主函数的输入被分为两个部分:课程相关信息和学生成绩信息。
通过字符串的正则匹配,判断输入的内容属于哪一类信息,并根据匹配结果进行相应的处理。
类和数据结构:
该代码中定义了四个类:Course、Class、Student和Curricula,分别表示课程、班级、学生和课程计划。
Course类包含课程的名称、类型和访问模式以及成绩权重的列表。
Class类包含班级的编号和学生列表。
Student类包含学生的学号和姓名。
Curricula类表示学生的选课计划,包含学生、成绩和课程的信息。
数据存储:
代码中使用了四个ArrayList来存储所有的课程、选课计划、班级和学生对象。
courses列表用于存储所有的课程对象。
curriculaVariables列表用于存储所有的选课计划对象。
classes列表用于存储所有的班级对象。
students列表用于存储所有的学生对象。
输入处理:
主函数使用Scanner对象从标准输入中读取用户输入的字符串。
使用正则表达式对输入的字符串进行匹配,确定其属于哪一类输入。
根据不同的输入类型,进行相应的处理操作,如创建课程对象、学生对象、选课计划对象等,并将它们添加到相应的列表中。
输出:
主函数的最后调用了output函数,用于输出学生成绩信息。
output函数先对学生列表进行排序,并遍历每个学生,计算其平均成绩并输出。
然后对课程列表进行排序,并遍历每门课程,计算平均成绩并输出。
其他功能:
代码中使用Collator类对课程列表进行排序,以支持中文课程名的排序。
代码中使用正则表达式进行输入的格式验证,例如检查权重值是否符合要求等。
心得:
题目不难,由于是慢慢迭代上来的,思路很清晰,设计完善的过程中并没有遇到什么问题。
三、踩坑心得
OOP训练集08
7-1 课程成绩统计程序-1
这道题由于简单而且有前面和这个题目类似的题做铺垫,以及这个题目是根据老师给的类图来完成整个程序的设计,按部就班的工作,一步一个脚印,以至于基本没踩坑。
OOP训练集11
7-2 课程成绩统计程序-3
这道题就比较坑了,前面也提到了,题目不难,由于是慢慢迭代上来的,思路很清晰,设计完善的过程中并没有遇到什么问题,所有样例都能过,个人感觉也没啥问题,该考虑到的都应该考虑到了,可是最后提交的时候分数却只有一半,又因为那几天比较忙,考试,4级之类的事情比较多,拿了一半分改进一晚上后还是没有得出结论就暂且没有管他。
1)浮点数的比较大小问题:
由于题目中存在分项成绩权重之和必须等于1的要求,而我却忘记这些权重都为浮点型而非整形,直接就判断是否!= 1,在这卡了很久,其实只需改成误差不超过0.001即可。
以下是更改后的判断规则:

结果上提示我少了个空格,就不知道是不是老师有意而为之了 ^ ^
2)实型与浮点型的区别:
由于习惯对于存在浮点数的计算问题,我都是统一用实型,毕竟精读更高,范围更广,这次依然是如此,可我怎么也没想到,老师给的测试点的计算结果都是统一的浮点型(float),这个是我向其他过了测试点的同学请教得来的,估计如果靠我自己的话,很难想出是这方面的问题。
以下是更改后的计算规则:

四、改进建议
OOP训练集08
7-1 课程成绩统计程序-1
综上所述,该代码在可读性、可维护性、可测试性、性能、可靠性、安全性和可扩展性方面表现良好。然而,仍然可以进一步优化,例如添加更多的异常处理、改进输入验证和错误处理等。此外,建议增加单元测试和注释的覆盖率,以提高代码质量和可靠性。
OOP训练集11
7-2 课程成绩统计程序-3
总体而言,代码在可读性、可维护性、可测试性、性能和可扩展性方面表现良好。但在安全性方面,代码没有直接涉及到安全问题的处理,需要根据具体场景和需求增加相应的安全措施。在可靠性方面,代码中的一些条件判断和错误输出可以帮助及时发现错误,但可能还有一些潜在的问题需要进一步检查和验证。需要根据具体的应用场景和需求,进行更全面的测试和验证。
五、总结
在这个阶段(10-16周)的学习中,我经历了一系列的编程题目集,涉及了菜单设计、课程成绩分析、正则表达式和字符替换、继承与多态等方面的知识。通过这些编程题目的完成,我对Java的基础语法和数据结构有了更深入的理解,并且提升了我的编程能力和问题解决能力。
首先,我学到了类的设计和组合的使用。在菜单设计和课程成绩分析的题目中,我需要合理地设计类和它们之间的关系,以实现程序的功能。这要求我考虑类的属性和方法的设计,以及如何合理地组织它们,使得程序结构清晰且易于扩展和维护。
其次,正则表达式的使用也是一个重要的学习点。在题目集9中,我需要使用正则表达式和字符替换来完成一些字符串的操作。通过这个题目,我学会了如何使用正则表达式来匹配和替换字符串,这在实际的文本处理中非常有用。
此外,继承和多态的概念和使用也是我在这个阶段学习到的内容。在题目集10中,有一道题目考查了继承和多态的应用。通过这道题目,我深入理解了继承和多态的概念,并学会了如何设计和使用具有继承关系的类,以及如何利用多态来实现灵活的程序设计。
在学习过程中,我还发现了一些需要进一步学习和研究的方面。首先,我需要深入学习设计模式和优秀的编程实践,以提高我的代码质量和可维护性。其次,我还需要进一步学习数据结构和算法的知识,以解决更复杂的问题并优化程序性能。此外,我还需要不断练习和实践,通过做更多的编程题目来提升自己的技能。
对于教师、课程、作业、实验、课上及课下组织方式等方面,我有一些改进建议和意见。首先,希望教师在讲解知识点时能够结合实际应用场景,让我们更好地理解知识的实际意义。其次,作业和实验可以设计得更加有挑战性和实用性,让我们能够更深入地理解和运用所学知识。此外,希望在课上能够有更多的互动和讨论,促进学生之间的交流和思维碰撞。最后,希望能够提供更多的学习资源和实践机会,以便我们能够更好地巩固所学知识。
总的来说,这个阶段的学习对我来说是非常有益的。我学到了很多实用的编程技巧和知识,提高了自己的编程能力。同时,我也认识到自己还有很多需要学习和提升的地方。通过不断学习和实践,我相信我能够进一步提高自己的编程水平,并应对更复杂的编程挑战。
六、结语
教学理念(OBE):
OBE(以学生为中心的教学)是一种重视学生学习成果和实际应用能力的教学理念。老师可以提供更多的案例和实际应用场景,引导学生主动思考和解决问题,从而培养学生的综合能力。
教学方法(边讲边练):
边讲边练是一种将理论知识和实践操作结合起来的教学方法,可以帮助学生更好地理解和掌握Java编程。但需要注意平衡讲解和练习的比例。建议增加更多的练习环节,提供更多的编程实践机会,让学生能够更深入地理解和掌握所学知识。
教学组织(线上线下混合式教学):
线上线下混合式教学可以充分利用在线学习平台和传统课堂教学的优势,提供灵活性和互动性。在线下教学时,教师应充分利用课堂时间进行实践演示和小组合作项目,以促进学生之间的互动和合作。
教学过程(PTA题目集驱动):
PTA题目集驱动的教学过程可以激发学生的学习兴趣和动力,但需要注意题目的难度和设计,确保选取的题目既有一定难度,又符合学生当前的知识水平。建议增加一些开放性的问题和项目,鼓励学生独立思考和解决问题,培养创新能力。
教学模式(BOPPPS):
BOPPPS模式的教学方式可以提高学生的参与度和学习效果,但需要确保每个环节的设计和实施都能够有效地引导学生学习。建议教师在每个环节中注重问题的质量和引导学生的深入思考,同时提供及时的反馈和评估,以促进学生的进步。
综合建议:
加强实践和应用能力培养:除了编程题目集,可以增加更多的实际项目和案例分析,让学生能够将所学知识应用到实际问题中。
强调团队合作和交流:鼓励学生进行团队项目和讨论,培养合作和沟通能力。
提供更多的学习资源和支持:为学生提供丰富的学习资料、在线讨论平台和指导,帮助他们更好地学习和掌握知识。
多样化评估方式:除了传统的考试和作业,可以引入项目评估、实践报告等多样化的评估方式,更全面地评价学生的学习成果。
不断更新教学内容和方法:紧跟科技和行业的发展,及时更新教学内容和方法,确保教学内容与实际需求相匹配。
总体而言,以上评价和建议都是为了提高教学质量和学生的学习效果。教师和学生可以相互配合,共同努力,不断改进和创新,为Java课程的教学提供更好的教育环境和学习体验。
感悟心得:
上大学也有一年了,唯一上课认真听讲,下课认真完成作业的课仅有Java,不单单是因为它是专业课,也不仅仅是因为它学分高(尽管高数一个学期6个学分,两个学期我学习高数的状态都是上课开小差,课后不完成作业,考前来突击,尽管每次考的都还算说的过去 ^ ^ ),是因为我真的有觉得在这门课上我能学到很多真正有用的东西,包括理念,思维等等。很多同学觉得老师有时候刻意刁难,有些行为很抽象,喜欢上课说说pao,装装b啥的,可能因为这些,他们不太喜欢段老师,听到后面可能不是段老师上课很开心,但实话实说我是很失落的,我是很喜欢段老师这个人,包括他的教学理念,他想在课堂上传达给同学们的思想,我都十分认同,我是第一次觉得一个老师这么有水平,不吹不黑,目前见到的个人认为水平最高的老师非段老师莫属了。段老师是个典型的刀子嘴豆腐心,天天拿挂科,取消考试资格吓学生,但到最后这些恐吓也不了了之了,这也算是他为同学们以后的升学就业操碎了心吧。所以,希望以后有机会,还能继续上段老师的专业课 ^ ^
—— 日立

浙公网安备 33010602011771号