一、前言
通过一个学期的学习,我们终于结束了面向对象程序设计这门课,在过去的几周时间内,我们进行了实验、pta以及最后的期末考试,课程虽然结束了,但需要学习和巩固的知识点还有很多,这也是最后一次blog总结。
显而易见,这两次的PTA作业所考察的知识点以及难度呈现不断变大的趋势。PTA6作业难度较难,是一个新的课程成绩统计程序,而PTA6和PTA7是在PTA5上增加难度,但是会有几个小题。三次PTA的作业着重练习类的构造方法、方法的调用、参数传递、对象的构造与使用;练习循环结构、控制结构;练习数据的输入与输出;学习编写结构清晰、逻辑正确、功能完善的java代码。学习使用工具对代码进行跟踪调试。理解抽象类与子类的关系,实现继承操作,构造类族;正确使用抽象类和子类实现多态操作;理解接口的意义,并实现行为的多态;理解了解抽象类、类以及接口三者的异同以及使用场合。掌握UML基本用法和画法,并能根据题目描述画出类、接口、类。整体题量较难,大部分的题目的难度适难,而且每个题目都有着鲜明的特点、特征。
二、设计与分析
第六次题目集:
题目分析:
此题是课程成绩统计程序,包含课程类,班级类,学生类和选课类,课程类主要是包含courseName,courseType和courseMode。学生类主要是包含ID和学生姓名,当然也要包含输入进来的成绩,包含期中和期末的成绩。输入的成绩不但要传入学生的图,还要把成绩传到课程和班级,这样传参又复杂了起来,一开始看到这个题目的时候,我是被吓了一跳的,因为这道题的文字量特别的大,而且加了许多别的功能,比如说删除和不对应,还有不输入成绩的情况,有这与普通成绩输入又有很大的区别。在得分上,得分点被细化,导致不好拿到高分。
以下是第六次题目集的代码:
import sys
class Course:
def __init__(self, name, prop, method):
self.name = name
self.prop = prop
self.method = method
self.grades = {} # 用于存储该课程的所有成绩信息
def add_grade(self, sid, name, quiz, exam):
"""
添加一条成绩记录
"""
if self.method == 'exam' and (not quiz or not exam):
# 如果该课程是考试方式,但没有平时成绩或期末成绩
print(f"{sid} {name}: access mode mismatch")
elif self.method == 'exam':
score = int(quiz * 0.3 + exam * 0.7) # 对成绩求加权平均值
else:
score = int(exam)
if score < 0 or score > 100:
# 如果成绩超出范围
print("wrong format")
else:
if self.name in courses:
# 存在该课程
course = courses[self.name]
if sid[:6] not in course.grades:
# 第一次添加该班级的成绩
course.grades[sid[:6]] = []
course.grades[sid[:6]].append(score)
else:
# 不存在该课程
print(f"{sid} {name}: {self.name} does not exist")
class Student:
def __init__(self, sid, name):
self.sid = sid
self.name = name
self.grades = [] # 用于存储该学生的所有成绩信息
def add_grade(self, name, quiz, exam):
self.grades.append((name, quiz, exam))
def average(self):
"""
计算该学生的所有课程的总成绩平均分
"""
if not self.grades:
return "did not take any exams"
total_score = sum(0.3 * quiz + 0.7 * exam for _, quiz, exam in self.grades)
return int(total_score / len(self.grades))
class CourseStatistics:
def __init__(self, course):
self.name = course.name
self.quiz_scores = []
self.exam_scores = []
self.total_scores = []
def add_grade(self, quiz, exam):
self.quiz_scores.append(quiz)
self.exam_scores.append(exam)
self.total_scores.append(int(quiz * 0.3 + exam * 0.7))
def average(self):
"""
计算该门课程的平均分
"""
quiz_average = round(sum(self.quiz_scores) / len(self.quiz_scores)) if self.quiz_scores else '-'
exam_average = round(sum(self.exam_scores) / len(self.exam_scores))
total_average = round(sum(self.total_scores) / len(self.total_scores))
return f"{self.name} {quiz_average} {exam_average} {total_average}"
class ClassStatistics:
def __init__(self, class_id):
self.class_id = class_id
self.total_scores = []
def add_score(self, score):
self.total_scores.append(score)
def average(self):
"""
计算该班级的所有课程的总成绩平均分
"""
if not self.total_scores:
return f"{self.class_id} has no grades yet"
return f"{self.class_id} {round(sum(self.total_scores) / len(self.total_scores))}"
def parse_course(line):
"""
从输入中解析一条课程记录
"""
fields = line.strip().split(' ')
name, prop = fields[0], fields[1]
if prop == '必修':
method = 'exam'
else:
method = fields[2] if len(fields) > 2 else 'exam'
return Course(name, prop, method)
def parse_grade(line):
"""
从输入中解析一条成绩记录
"""
fields = line.strip().split(' ')
sid, name, course_name = fields[0], fields[1], fields[2]
quiz, exam = map(int, fields[3:5]) if len(fields) == 5 else (None, int(fields[3]))
return sid, name, course_name, quiz, exam
# 读入输入数据
num_courses = int(input())
courses = {}
for _ in range(num_courses):
line = input()
course = parse_course(line)
courses[course.name] = course
num_grades = int(input())
students = {}
for _ in range(num_grades):
sid, name, course_name, quiz, exam = parse_grade(input())
if sid not in students:
# 第一次添加该学号的成绩
students[sid] = Student(sid, name)
students[sid].add_grade(course_name, quiz, exam)
if course_name in courses:
# 存在该课程
courses[course_name].add_grade(sid, name, quiz, exam)
else:
# 不存在该课程
print(f"{sid} {name}: {course_name} does not exist")
# 计算并输出各种统计量
student_stats = []
for sid, student in students.items():
student_stats.append(f"{sid} {student.name} {student.average()}")
student_stats.sort()
for line in student_stats:
print(line)
course_stats = []
for course_name, course in sorted(courses.items()):
stats = CourseStatistics(course)
for class_id, scores in course.grades.items():
for score in scores:
stats.add_grade(score, score)
course_stats.append(stats.average())
print(stats.average())
if not stats.exam_scores:
# 如果没有期末成绩,则该课程没有成绩信息
print(f"{course_name} has no grades yet")
class_stats = []
for class_id in sorted(set(sid[:6] for sid in students)):
stats = ClassStatistics(class_id)
for sid, student in students.items():
if sid.startswith(class_id):
stats.add_score(student.average())
class_stats.append(stats.average())
print(stats.average())
if not stats.total_scores:
# 如果该班级没有成绩信息
print(f"{class_id} has no grades yet")
类图如下:
圈复杂度如下:
本次题目因为是刚接触课程计价程序,所以做起来感觉有点难度,然后因为时间也比较紧张,所以我就只得到一点分。
踩坑心得:
1,成绩平均分只取整数部分,小数部分丢弃,要分开取整,不能加在一起取整。
2,格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format",输出后用continue而不能简单的用break。
3,超出范围的返回值错误,导致返回空。
4,方法后没有带上(),导致报错,所以方法类函数后都要加上()。
5,大小写注意,java语言对输入的语言的精确度和精准度要去很高,很多时候报错是因为方法首字母没有大写。
6,排序时用的冒泡排序,导致经常出错,还是普通的循环排序更靠谱。
第六次题目集:
题目分析:这次题目将课程计价程序2分成了几个小题,所以上手难度更简单一些,再加上有这几个小题的铺垫。所以做起来更加得心应手。
此题是课程成绩统计程序,包含课程类,班级类,学生类和选课类,课程类主要是包含courseName,courseType和courseMode。学生类主要是包含ID和学生姓名,当然也要包含输入进来的成绩,包含期中和期末的成绩。输入的成绩不但要传入学生的图,还要把成绩传到课程和班级,这样传参又复杂了起来。并且这次加入了实验这个新的ourseType和courseMode,实验的成绩又是另一种算法,所以我采取了边输入边算,然后在传参的方法,输入后马上清空列表开始计算下一个人的成绩,实验实验类确实是特别的存在,有自己的独特算法,导致我要新建一个实验成绩类,而且在主函数里面又增加了很多情况。课程性质分为必修课、选修课和实验课。考核方式分为考试、考察和实验。不同考核方式对总成绩的影响也不同。其中,考试的总成绩由平时成绩和期末成绩的权重决定,考察的总成绩直接等于期末成绩,实验的总成绩为每次实验成绩的平均分。在这个程序中,必修课只能选择考试作为考核方式,选修课可以选择考试或考察,而实验课的成绩只能由实验的成绩计算得出。
此题代码如下:
import java.util.*;
// 学生类
class Student {
private String studentId;
private String name;
public Student(String studentId, String name) {
this.studentId = studentId;
this.name = name;
}
public String getStudentId() {
return studentId;
}
public String getName() {
return name;
}
}
// 课程类
class Course {
private String courseName;
private String courseType;
private String assessmentMode;
public Course(String courseName, String courseType, String assessmentMode) {
this.courseName = courseName;
this.courseType = courseType;
this.assessmentMode = assessmentMode;
}
public String getCourseName() {
return courseName;
}
public String getCourseType() {
return courseType;
}
public String getAssessmentMode() {
return assessmentMode;
}
}
// 成绩类
abstract class Score {
private int score;
private String course;
public String getCourse() {
return course;
}
public Score setCourse(String course) {
this.course = course;
return this;
}
public Score(int score, String course) {
this.score = score;
this.course = course;
}
public int getScore() {
return score;
}
public Score setScore(int score) {
this.score = score;
return this;
}
public abstract int calculateTotalScore();
}
// 考试成绩类
class ExamScore extends Score {
private int ordinaryScore;
private int finalScore;
public ExamScore(String course, int ordinaryScore, int finalScore) {
super((int) (ordinaryScore * 0.3 + finalScore * 0.7), course);
this.ordinaryScore = ordinaryScore;
this.finalScore = finalScore;
}
public int getOrdinaryScore() {
return ordinaryScore;
}
public ExamScore setOrdinaryScore(int ordinaryScore) {
this.ordinaryScore = ordinaryScore;
return this;
}
public int getFinalScore() {
return finalScore;
}
public ExamScore setFinalScore(int finalScore) {
this.finalScore = finalScore;
return this;
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 考察成绩类
class ReviewScore extends Score {
public int ordinaryScore;
public int getOrdinaryScore() {
return ordinaryScore;
}
public ReviewScore setOrdinaryScore(int ordinaryScore) {
this.ordinaryScore = ordinaryScore;
return this;
}
public ReviewScore(String course, int ordinaryScore, int score) {
super(score, course);
this.ordinaryScore = ordinaryScore;
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 实验成绩类
class LabScore extends Score {
private List<Integer> Score;
public LabScore(String course, List<Integer> score) {
super(score.stream().reduce(Integer::sum).orElse(0) / score.size(), course);
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 主程序类
public class Main {
private Map<String, Student> students;
private Map<String, Course> courses;
private Map<String, List<Score>> scores;
public Main() {
students = new HashMap<>();
courses = new HashMap<>();
scores = new HashMap<>();
}
public void processInput(String input) {
String[] tokens = input.split(" ");
String type = tokens[0];
if (type.matches("[0-9]+")) {
processScore(tokens);
} else if (type.equals("end")) {
calculateGrades();
} else {
processCourse(tokens);
}
// switch (type) {
// case "java":
// case "C语言":
// case "编译原理":
// processCourse(tokens);
// break;
// case "end":
// calculateGrades();
// break;
// default:
// processScore(tokens);
// break;
// }
}
private void processCourse(String[] tokens) {
String courseName = tokens[0];
String courseType = tokens[1];
String assessmentMode = tokens[2];
if (courseType.equals("必修") && !assessmentMode.equals("考试")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if (courseType.equals("考察") && assessmentMode.equals("实验")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if (courseType.equals("实验") && !assessmentMode.equals("实验")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if(courses.get(courseName)==null) {
Course course = new Course(courseName, courseType, assessmentMode);
courses.put(courseName, course);
}
}
private void processScore(String[] tokens) {
String studentId = tokens[0];
String name = tokens[1];
String courseName = tokens[2];
boolean b = true;
for (int i = 3; i < tokens.length; i++) {
String token = tokens[i];
int i1 = Integer.parseInt(token);
if (i1 > 100 || i1 < 0) {
System.out.println("wrong format");
b = false;
return;
}
}
if (tokens.length > 5) {
int testNumber = Integer.parseInt(tokens[3]);
if (testNumber < 4 || testNumber > 9) {
System.out.println("wrong format");
b = false;
return;
}
Course course = courses.get(courseName);
if (course == null) {
System.out.println(studentId + " " + name + " : " + courseName + " does not exist");
return;
}
if (tokens.length - 4 != testNumber) {
System.out.println(studentId + " " + name + " : access mode mismatch");
Student student = students.get(studentId);
if (student == null) {
student = new Student(studentId, name);
students.put(studentId, student);
}
return;
}
}
if (b) {
Student student = students.get(studentId);
if (student == null) {
student = new Student(studentId, name);
students.put(studentId, student);
}
}
Course course = courses.get(courseName);
if (course == null) {
System.out.println(studentId + " " + name + " : " + courseName + " does not exist");
return;
}
String courseType = course.getCourseType();
String assessmentMode = course.getAssessmentMode();
int numScores = tokens.length - 3;
if (courseType.equals("必修") && numScores != 2) {
System.out.println(studentId + " " + name + " : access mode mismatch");
}
if ((numScores > 2 || numScores < 1) && (assessmentMode.equals("考察"))) {
System.out.println(studentId + " " + name + " : access mode mismatch");
}
List<Score> scoreList = scores.get(studentId);
if (scoreList == null) {
scoreList = new ArrayList<>();
scores.put(studentId, scoreList);
}
switch (assessmentMode) {
case "考试":
int ordinaryScore = Integer.parseInt(tokens[3]);
int finalScore = Integer.parseInt(tokens[4]);
ExamScore examScore = new ExamScore(courseName, ordinaryScore, finalScore);
scoreList.add(examScore);
break;
case "考察":
if (numScores == 1) {
int reviewScore = Integer.parseInt(tokens[3]);
scoreList.add(new ReviewScore(courseName, 0, reviewScore));
} else {
int ordinaryScores = Integer.parseInt(tokens[3]);
int reviewScore = Integer.parseInt(tokens[4]);
scoreList.add(new ReviewScore(courseName, ordinaryScores, reviewScore));
}
break;
case "实验":
List<Integer> labScores = new ArrayList<>();
for (int i = 4; i < tokens.length; i++) {
int labScore = Integer.parseInt(tokens[i]);
labScores.add(labScore);
}
scoreList.add(new LabScore(courseName, labScores));
break;
}
}
private void calculateGrades() {
List<String> studentIds = new ArrayList<>(students.keySet());
Collections.sort(studentIds);
for (String studentId : studentIds) {
Student student = students.get(studentId);
List<Score> scoreList = scores.get(studentId);
if (scoreList == null || scoreList.isEmpty()) {
System.out.println(studentId + " " + student.getName() + " did not take any exams");
continue;
}
int totalScore = calculateTotalScore(scoreList);
int averageScore = totalScore / scoreList.size();
System.out.println(studentId + " " + student.getName() + " " + averageScore);
}
List<String> courseNames = new ArrayList<>(courses.keySet());
Collections.sort(courseNames);
for (String courseName : courseNames) {
Course course = courses.get(courseName);
String courseType = course.getCourseType();
String assessmentMode = course.getAssessmentMode();
List<Integer> examScores = new ArrayList<>();
List<Integer> ordinaryScores = new ArrayList<>();
List<Integer> totalScores = new ArrayList<>();
List<Integer> labScores = new ArrayList<>();
for (String studentId : scores.keySet()) {
List<Score> scoreList = scores.get(studentId);
Score score = findScoreByCourse(scoreList, courseName);
if (score == null) {
continue;
}
if (score instanceof ExamScore) {
ExamScore examScore = (ExamScore) score;
examScores.add(examScore.getFinalScore());
ordinaryScores.add(examScore.getOrdinaryScore());
totalScores.add(examScore.getScore());
} else if (score instanceof ReviewScore) {
ReviewScore reviewScore = (ReviewScore) score;
ordinaryScores.add(reviewScore.getOrdinaryScore());
examScores.add(reviewScore.getScore());
} else if (score instanceof LabScore) {
LabScore labScore = (LabScore) score;
labScores.add(labScore.getScore());
}
}
//
int averageExamScore = calculateAverage(examScores);
int averageOrdinaryScore = (calculateAverage(ordinaryScores) != 0) ? calculateAverage(ordinaryScores) : calculateAverage(examScores);
int averageLabScore = calculateAverage(labScores);
int averageTotalScore = calculateAverage(totalScores);
if (assessmentMode.equals("考试")) {
System.out.println(courseName + " " + averageOrdinaryScore + " " + averageExamScore + " " + averageTotalScore);
} else if (assessmentMode.equals("考察")) {
System.out.println(courseName + " " + averageOrdinaryScore + " " + averageExamScore);
} else if (assessmentMode.equals("实验")) {
System.out.println(courseName + " " + (averageLabScore != 0 ? averageLabScore : "has no grades yet"));
}
}
List<String> classIds = getClassIds();
Collections.sort(classIds);
for (String classId : classIds) {
List<String> studentsInClass = getStudentsInClass(classId);
int totalScore = 0;
int count = 0;
for (String studentId : studentsInClass) {
List<Score> scoreList = scores.get(studentId);
if (scoreList != null) {
for (Score score : scoreList) {
totalScore += score.getScore();
count++;
}
}
}
if (count > 0) {
int averageScore = totalScore / count;
System.out.println(classId + " " + averageScore);
} else {
System.out.println(classId + " has no grades yet");
}
}
}
private Score findScoreByCourse(List<Score> scoreList, String courseName) {
for (Score score : scoreList) {
if (score.getCourse().equals(courseName)) {
return score;
}
}
return null;
}
private int calculateTotalScore(List<Score> scoreList) {
int totalScore = 0;
for (Score score : scoreList) {
totalScore += score.getScore();
}
return totalScore;
}
private int calculateAverage(List<Integer> scores) {
int total = 0;
if (scores.size() != 0) {
for (int score : scores) {
total += score;
}
return total / scores.size();
}
return 0;
}
private List<String> getClassIds() {
List<String> classIds = new ArrayList<>();
for (String studentId : students.keySet()) {
String classId = studentId.substring(0, 6);
if (!classIds.contains(classId)) {
classIds.add(classId);
}
}
return classIds;
}
private List<String> getStudentsInClass(String classId) {
List<String> studentsInClass = new ArrayList<>();
for (String studentId : students.keySet()) {
if (studentId.startsWith(classId)) {
studentsInClass.add(studentId);
}
}
return studentsInClass;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Main scoreStatistics = new Main();
StringBuffer stringBuffer = new StringBuffer();
while (scanner.hasNextLine()) {
String input = scanner.nextLine();
stringBuffer.append(input).append("\n");
if (input.equals("end")) {
break;
}
}
scoreStatistics.processAllInput(stringBuffer.toString());
}
private void processAllInput(String allInput) {
String[] input = allInput.split("\n");
for (String s : input) {
processInput(s);
}
}
}
类图如下:
圈复杂度如下:
踩坑心得:
1;成绩平均分只取整数部分,小数部分丢弃,要分开取整,不能加在一起取整。上次的pta这个不是很明显,但这次有部分测试点的分数确实蹊跷,正好要四舍五入。
2;格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format",输出后用continue而不能简单的用break。
3,超出范围的返回值错误,导致返回空。
4;方法后没有带上(),导致报错,所以方法类函数后都要加上()。
5,大小写注意,java语言对输入的语言的精确度和精准度要去很高,很多时候报错是因为方法首字母没有大写。
6,排序时用的冒泡排序,导致经常出错,还是普通的循环排序更靠谱。
7,数据类型转换错误,string类和int类转换和输出问题。
8,代码需要传参的地方更多,很容易传参错误导致输出错误。
9,不同的四舍五入顺序可能会造成误差。
第八次题目集:
题目分析:本次题目集形式与第七次差不多,但是在难度上有所提升。
此题是课程成绩统计程序,包含课程类,班级类,学生类和选课类,课程类主要是包含courseName,courseType和courseMode。学生类主要是包含ID和学生姓名,当然也要包含输入进来的成绩,包含期中和期末的成绩。输入的成绩不但要传入学生的图,还要把成绩传到课程和班级,这样传参又复杂了起来。并且这次加入了实验这个新的ourseType和courseMode,实验的成绩又是另一种算法,所以我采取了边输入边算,然后在传参的方法,输入后马上清空列表开始计算下一个人的成绩。在第三个版本中,修改了计算总成绩的方式,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成。课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。这次的实验类还加入了权重,有事动态的输入,有需要传参,和动态的存入,十分的复杂。考试的总成绩由平时成绩和期末成绩的权重决定,考察的总成绩直接等于期末成绩,实验的总成绩为课程每次实验成绩乘以权重后累加。在录入课程信息时,需要输入课程权重值,并确保所有分项成绩的权重之和等于1。
本题代码如下:
import java.util.*;
// 学生类
class Student {
private String studentId;
private String name;
public Student(String studentId, String name) {
this.studentId = studentId;
this.name = name;
}
public String getStudentId() {
return studentId;
}
public String getName() {
return name;
}
}
// 课程类
class Course {
private String courseName;
private String courseType;
private String assessmentMode;
public Course(String courseName, String courseType, String assessmentMode) {
this.courseName = courseName;
this.courseType = courseType;
this.assessmentMode = assessmentMode;
}
public String getCourseName() {
return courseName;
}
public String getCourseType() {
return courseType;
}
public String getAssessmentMode() {
return assessmentMode;
}
}
// 成绩类
abstract class Score {
private int score;
private String course;
public String getCourse() {
return course;
}
public Score setCourse(String course) {
this.course = course;
return this;
}
public Score(int score, String course) {
this.score = score;
this.course = course;
}
public int getScore() {
return score;
}
public Score setScore(int score) {
this.score = score;
return this;
}
public abstract int calculateTotalScore();
}
// 考试成绩类
class ExamScore extends Score {
private int ordinaryScore;
private int finalScore;
public ExamScore(String course, int ordinaryScore, int finalScore) {
super((int) (ordinaryScore * 0.3 + finalScore * 0.7), course);
this.ordinaryScore = ordinaryScore;
this.finalScore = finalScore;
}
public int getOrdinaryScore() {
return ordinaryScore;
}
public ExamScore setOrdinaryScore(int ordinaryScore) {
this.ordinaryScore = ordinaryScore;
return this;
}
public int getFinalScore() {
return finalScore;
}
public ExamScore setFinalScore(int finalScore) {
this.finalScore = finalScore;
return this;
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 考察成绩类
class ReviewScore extends Score {
public int ordinaryScore;
public int getOrdinaryScore() {
return ordinaryScore;
}
public ReviewScore setOrdinaryScore(int ordinaryScore) {
this.ordinaryScore = ordinaryScore;
return this;
}
public ReviewScore(String course, int ordinaryScore, int score) {
super(score, course);
this.ordinaryScore = ordinaryScore;
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 实验成绩类
class LabScore extends Score {
private List<Integer> Score;
public LabScore(String course, List<Integer> score) {
super(score.stream().reduce(Integer::sum).orElse(0) / score.size(), course);
}
@Override
public int calculateTotalScore() {
return getScore();
}
}
// 主程序类
public class Main {
private Map<String, Student> students;
private Map<String, Course> courses;
private Map<String, List<Score>> scores;
public Main() {
students = new HashMap<>();
courses = new HashMap<>();
scores = new HashMap<>();
}
public void processInput(String input) {
String[] tokens = input.split(" ");
String type = tokens[0];
if (type.matches("[0-9]+")) {
processScore(tokens);
} else if (type.equals("end")) {
calculateGrades();
} else {
processCourse(tokens);
}
// switch (type) {
// case "java":
// case "C语言":
// case "编译原理":
// processCourse(tokens);
// break;
// case "end":
// calculateGrades();
// break;
// default:
// processScore(tokens);
// break;
// }
}
private void processCourse(String[] tokens) {
String courseName = tokens[0];
String courseType = tokens[1];
String assessmentMode = tokens[2];
if (courseType.equals("必修") && !assessmentMode.equals("考试")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if (courseType.equals("考察") && assessmentMode.equals("实验")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if (courseType.equals("实验") && !assessmentMode.equals("实验")) {
System.out.println(courseName + " : course type & access mode mismatch");
return;
}
if(courses.get(courseName)==null) {
Course course = new Course(courseName, courseType, assessmentMode);
courses.put(courseName, course);
}
}
private void processScore(String[] tokens) {
String studentId = tokens[0];
String name = tokens[1];
String courseName = tokens[2];
boolean b = true;
for (int i = 3; i < tokens.length; i++) {
String token = tokens[i];
int i1 = Integer.parseInt(token);
if (i1 > 100 || i1 < 0) {
System.out.println("wrong format");
b = false;
return;
}
}
if (tokens.length > 5) {
int testNumber = Integer.parseInt(tokens[3]);
if (testNumber < 4 || testNumber > 9) {
System.out.println("wrong format");
b = false;
return;
}
Course course = courses.get(courseName);
if (course == null) {
System.out.println(studentId + " " + name + " : " + courseName + " does not exist");
return;
}
if (tokens.length - 4 != testNumber) {
System.out.println(studentId + " " + name + " : access mode mismatch");
Student student = students.get(studentId);
if (student == null) {
student = new Student(studentId, name);
students.put(studentId, student);
}
return;
}
}
if (b) {
Student student = students.get(studentId);
if (student == null) {
student = new Student(studentId, name);
students.put(studentId, student);
}
}
Course course = courses.get(courseName);
if (course == null) {
System.out.println(studentId + " " + name + " : " + courseName + " does not exist");
return;
}
String courseType = course.getCourseType();
String assessmentMode = course.getAssessmentMode();
int numScores = tokens.length - 3;
if (courseType.equals("必修") && numScores != 2) {
System.out.println(studentId + " " + name + " : access mode mismatch");
}
if ((numScores > 2 || numScores < 1) && (assessmentMode.equals("考察"))) {
System.out.println(studentId + " " + name + " : access mode mismatch");
}
List<Score> scoreList = scores.get(studentId);
if (scoreList == null) {
scoreList = new ArrayList<>();
scores.put(studentId, scoreList);
}
switch (assessmentMode) {
case "考试":
int ordinaryScore = Integer.parseInt(tokens[3]);
int finalScore = Integer.parseInt(tokens[4]);
ExamScore examScore = new ExamScore(courseName, ordinaryScore, finalScore);
scoreList.add(examScore);
break;
case "考察":
if (numScores == 1) {
int reviewScore = Integer.parseInt(tokens[3]);
scoreList.add(new ReviewScore(courseName, 0, reviewScore));
} else {
int ordinaryScores = Integer.parseInt(tokens[3]);
int reviewScore = Integer.parseInt(tokens[4]);
scoreList.add(new ReviewScore(courseName, ordinaryScores, reviewScore));
}
break;
case "实验":
List<Integer> labScores = new ArrayList<>();
for (int i = 4; i < tokens.length; i++) {
int labScore = Integer.parseInt(tokens[i]);
labScores.add(labScore);
}
scoreList.add(new LabScore(courseName, labScores));
break;
}
}
private void calculateGrades() {
List<String> studentIds = new ArrayList<>(students.keySet());
Collections.sort(studentIds);
for (String studentId : studentIds) {
Student student = students.get(studentId);
List<Score> scoreList = scores.get(studentId);
if (scoreList == null || scoreList.isEmpty()) {
System.out.println(studentId + " " + student.getName() + " did not take any exams");
continue;
}
int totalScore = calculateTotalScore(scoreList);
int averageScore = totalScore / scoreList.size();
System.out.println(studentId + " " + student.getName() + " " + averageScore);
}
List<String> courseNames = new ArrayList<>(courses.keySet());
Collections.sort(courseNames);
for (String courseName : courseNames) {
Course course = courses.get(courseName);
String courseType = course.getCourseType();
String assessmentMode = course.getAssessmentMode();
List<Integer> examScores = new ArrayList<>();
List<Integer> ordinaryScores = new ArrayList<>();
List<Integer> totalScores = new ArrayList<>();
List<Integer> labScores = new ArrayList<>();
for (String studentId : scores.keySet()) {
List<Score> scoreList = scores.get(studentId);
Score score = findScoreByCourse(scoreList, courseName);
if (score == null) {
continue;
}
if (score instanceof ExamScore) {
ExamScore examScore = (ExamScore) score;
examScores.add(examScore.getFinalScore());
ordinaryScores.add(examScore.getOrdinaryScore());
totalScores.add(examScore.getScore());
} else if (score instanceof ReviewScore) {
ReviewScore reviewScore = (ReviewScore) score;
ordinaryScores.add(reviewScore.getOrdinaryScore());
examScores.add(reviewScore.getScore());
} else if (score instanceof LabScore) {
LabScore labScore = (LabScore) score;
labScores.add(labScore.getScore());
}
}
//
int averageExamScore = calculateAverage(examScores);
int averageOrdinaryScore = (calculateAverage(ordinaryScores) != 0) ? calculateAverage(ordinaryScores) : calculateAverage(examScores);
int averageLabScore = calculateAverage(labScores);
int averageTotalScore = calculateAverage(totalScores);
if (assessmentMode.equals("考试")) {
System.out.println(courseName + " " + averageOrdinaryScore + " " + averageExamScore + " " + averageTotalScore);
} else if (assessmentMode.equals("考察")) {
System.out.println(courseName + " " + averageOrdinaryScore + " " + averageExamScore);
} else if (assessmentMode.equals("实验")) {
System.out.println(courseName + " " + (averageLabScore != 0 ? averageLabScore : "has no grades yet"));
}
}
List<String> classIds = getClassIds();
Collections.sort(classIds);
for (String classId : classIds) {
List<String> studentsInClass = getStudentsInClass(classId);
int totalScore = 0;
int count = 0;
for (String studentId : studentsInClass) {
List<Score> scoreList = scores.get(studentId);
if (scoreList != null) {
for (Score score : scoreList) {
totalScore += score.getScore();
count++;
}
}
}
if (count > 0) {
int averageScore = totalScore / count;
System.out.println(classId + " " + averageScore);
} else {
System.out.println(classId + " has no grades yet");
}
}
}
private Score findScoreByCourse(List<Score> scoreList, String courseName) {
for (Score score : scoreList) {
if (score.getCourse().equals(courseName)) {
return score;
}
}
return null;
}
private int calculateTotalScore(List<Score> scoreList) {
int totalScore = 0;
for (Score score : scoreList) {
totalScore += score.getScore();
}
return totalScore;
}
private int calculateAverage(List<Integer> scores) {
int total = 0;
if (scores.size() != 0) {
for (int score : scores) {
total += score;
}
return total / scores.size();
}
return 0;
}
private List<String> getClassIds() {
List<String> classIds = new ArrayList<>();
for (String studentId : students.keySet()) {
String classId = studentId.substring(0, 6);
if (!classIds.contains(classId)) {
classIds.add(classId);
}
}
return classIds;
}
private List<String> getStudentsInClass(String classId) {
List<String> studentsInClass = new ArrayList<>();
for (String studentId : students.keySet()) {
if (studentId.startsWith(classId)) {
studentsInClass.add(studentId);
}
}
return studentsInClass;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Main scoreStatistics = new Main();
StringBuffer stringBuffer = new StringBuffer();
while (scanner.hasNextLine()) {
String input = scanner.nextLine();
stringBuffer.append(input).append("\n");
if (input.equals("end")) {
break;
}
}
scoreStatistics.processAllInput(stringBuffer.toString());
}
private void processAllInput(String allInput) {
String[] input = allInput.split("\n");
for (String s : input) {
processInput(s);
}
}
}
类图如下:
圈复杂度如下:
踩坑心得:
1,在比较两个字符串时,可以使用 String 的 compareTo 方法,而不是将字符串转换为整数进行比较。因为这样会损失精度,还会增加代码的复杂性。所以,继续使用 compareTo 方法来比较两个学生的编号。
2,目前的代码只能计算学生的总分和平均分,如果需要计算其他的统计信息,比如最高分、最低分,就需要修改代码。可以考虑将这些计算逻辑抽象成一个 ScoreCalculator 类,并使用策略模式来支持不同的统计方法。这样可以让代码更加灵活,易于扩展。
3,自我判断:IfRight() 方法判断成绩数组的长度和每个元素的取值是否正确。这个方法不够通用,应该分离出去。可以考虑在 Score 类中添加一个构造函数,该构造函数接受成绩数组并验证它们的长度和取值是否正确。如果参数不符合要求,则抛出 IllegalArgumentException 异常。
主要困难以及改进建议:
课程成绩统计程序方面做的不好,类与对象的知识点没有掌握好,功能实现不完整。对多项式求导还有待改进,没能完全实现多项式求导功能,圈复杂度无法控制。在控制圈复杂度上还有待改进,三次题目集的圈复杂度都没在10以下,在降低圈复杂的方面还有待研究,了解圈复杂度过高的原因,如何在设计之初就降低圈复杂度,尽量不要在实现完功能后,在去修改圈复杂度思维僵化,死板。在写题目过程中,不能灵活的调用知识,即使掌握了新知识点,仍然沿用以前的思维考虑题目,查错能力低。不能系统的思考问题产生的原因,思考如何解决问题,而是不断地运行程序,不断地进行输入操作,阅读题目不仔细。在没能完全理解题目要求的情况下,就开始思考如何解决题目,一味的求快,在最后需要花费更多的时间来查错。
总结:
首先在这里我使用了新的知识java,同时也学到了如何使用字符串中的方法,同时还学到了创建一个新的类,对我在这几道题的帮助特别大,同时我还需要继续学习父类和子类之间如何使用的,同时老师在对我们学习这方面帮助很大,作业和实验每次也都刚刚好,希望老师在课上时能够多多与示例相结合来讲解书本内容。但是这几次作业总体来说自己做的不是很好,虽然if-else知识点掌握情况较好,对变量的定义输出也掌握较好,但是类与对象方面知识点掌握不够好,在以后的学习中,我一定会对自己不足的知识点进行补充。
标签:studentId,return,String,int,BLOG3,course,score From: https://www.cnblogs.com/zqq666/p/17500684.html