PTA6-8次题目集(成绩计算系列)总结

发布时间 2023-06-23 13:20:20作者: HEALERɷ

1.前言

6-8次作业题量不大,难度较菜单计价较小,但实现过程依旧繁琐

知识点

  1. 输入和输出处理:你需要从用户或文件中读取输入数据(课程信息和学生成绩),然后相应地进行处理。你可以使用诸如读取控制台输入(Scanner 类)或从文件读取技术。

  2. 字符串操作和解析:你需要将输入的字符串分割后提取相关的信息,如课程名称、课程性质、考核方式、学号、姓名、成绩等。Java 提供了各种字符串操作的方法,如 split()substring()indexOf() 等。

  3. 数据结构:你需要使用适当的数据结构来存储和操作课程和成绩信息。例如,你可以使用 ArrayList 来存储和获取课程详情。

  4. 排序和过滤:你需要使用技术对学生成绩按照学号进行排序、计算平均分、过滤掉没有成绩的课程等。Java 提供了像 Collections.sort()filter() 和 average() 这样的方法来实现这些操作。

  5. 错误处理:你应该处理程序执行过程中可能出现的错误或异常,比如输入格式错误、无效的成绩、访问模式不匹配等。可以使用 try-catch 块或自定义的异常处理来实现。

  6. 条件语句和循环:你需要使用条件语句(ifswitch)和循环(forwhile)在处理数据时进行各种检查和迭代

2.设计与分析

7-1 课程成绩统计程序-1

源码:

import java.text.Collator;
import java.util.*;

public class Main {
/**
* 课程类
*/
static class Course implements Comparable<Course> {
String name; // 课程名称
String nature; // 课程性质(必修或选修)
String examType; // 考核方式(考试或考察)

public Course(String name, String nature, String examType) {
this.name = name;
this.nature = nature;
this.examType = examType;
}

public Course() {}

@Override
public int compareTo(Course o) {
return o.name.compareTo(this.name);
}
}
/**
* 成绩类
*/
static class Grade {
String studentId; // 学号
String name; // 姓名
String courseName; // 课程名称
int usualScore; // 平时成绩
int examScore; // 期末成绩

public Grade(String studentId, String name, String courseName, int usualScore, int examScore) {
this.studentId = studentId;
this.name = name;
this.courseName = courseName;
this.usualScore = usualScore;
this.examScore = examScore;
}

public Grade() {}
}

private static List<Course> courses = new ArrayList<>();
private static Map<String, List<Grade>> sgs = new TreeMap<>();
private static Map<String, List<Grade>> cgs = new HashMap<>();
private static Map<String, List<Grade>> clgs = new TreeMap<>();

public static void main(String[] args) {
// System.out.println("数据结构".compareTo("数据库"));
// System.out.println("java".compareTo("数据结构"));
Scanner scanner = new Scanner(System.in);
String inputStr = scanner.nextLine();
while (!inputStr.equals("end")) {
String [] strs = inputStr.split(" ");
if (strs.length > 3) {
addGrade(strs);
} else {
addCourse(strs);
}
inputStr = scanner.nextLine();
}
listSort(courses);
printStu();
printCourse();
printClass();
}

// 课程排序
public static void listSort(List<Course> resultList) {
Collections.sort(resultList, new Comparator<Course>() {
public int compare(Course o1, Course o2) {
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(o1.name, o2.name);
}
});
}

private static void printClass() {
for (String cl : clgs.keySet()) {
int sum = 0;
for (Grade grade : clgs.get(cl)) {
for (Course course : courses) {
if (course.name.equals(grade.courseName)) {
if (course.examType.equals("考试")) {
sum += (int)(grade.usualScore * 0.3 + grade.examScore * 0.7);
} else {
sum += grade.examScore;
}
}
}
}
System.out.println(cl + " " + (sum / clgs.get(cl).size()));
}

}

private static void printCourse() {
for (Course course : courses) {
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
if (!cgs.keySet().contains(course.name)) {
System.out.println(course.name + " has no grades yet");
continue;
}
for (String name : cgs.keySet()) {
if (name.equals(course.name)) {
for (Grade grade : cgs.get(name)) {
sum1 += grade.usualScore;
sum2 += grade.examScore;
if (course.examType.equals("考试")) {
sum3 += (int)(grade.usualScore * 0.3 + grade.examScore * 0.7);
} else {
sum3 += grade.examScore;
}
}
}
}
int len = cgs.get(course.name).size();
if (course.examType.equals("考试")) {
System.out.println(course.name + " " + (sum1 / len) + " " + (sum2 / len) + " " + (sum3 / len));
} else {
System.out.println(course.name + " " + (sum2 / len) + " " + (sum3 / len));
}
}
}

private static void printStu() {
for (String stu : sgs.keySet()) {
int sum = 0;
for (Grade grade : sgs.get(stu)) {
for (Course course : courses) {
if (course.name.equals(grade.courseName)) {
if (course.examType.equals("考试")) {
sum += (int) (grade.usualScore * 0.3 + grade.examScore * 0.7);
} else {
sum += grade.examScore;
}
}
}
}
System.out.println(sgs.get(stu).get(0).studentId + " " + sgs.get(stu).get(0).name + " " + (sum / sgs.get(stu).size()));
}
}

private static void addGrade(String[] strs) {
try {
boolean f = false;
for (Course course : courses) {
if (course.name.equals(strs[2])) {
f = true;
}
}
if (!f) {
System.out.println(strs[2] + " does not exist");
return;
}
Grade grade = new Grade();
grade.studentId = strs[0];
grade.name = strs[1];
grade.courseName = strs[2];
for (Course course : courses) {
if (course.name.equals(strs[2])) {
if (course.examType.equals("考试") && strs.length == 4) {
System.out.println(strs[0] + " " + strs[1] + " : access mode mismatch");
return;
}
}
}
if (strs.length == 5) {
grade.usualScore = Integer.parseInt(strs[3]);
grade.examScore = Integer.parseInt(strs[4]);
} else if (strs.length == 4) {
grade.examScore = Integer.parseInt(strs[3]);
}
if (grade.usualScore > 100 || grade.usualScore < 0 || grade.examScore > 100 || grade.examScore < 0) {
System.out.println("wrong format");
return;
}
List<Grade> grades = sgs.get(strs[0]);
if (grades == null) {
grades = new ArrayList<>();
sgs.put(strs[0], grades);
}
List<Grade> grades1 = cgs.get(strs[2]);
if (grades1 == null) {
grades1 = new ArrayList<>();
cgs.put(strs[2], grades1);
}
String cl = strs[0].substring(0, 6);
List<Grade> grades2 = clgs.get(cl);
if (grades2 == null) {
grades2 = new ArrayList<>();
clgs.put(cl, grades2);
}
grades.add(grade);
grades1.add(grade);
grades2.add(grade);
} catch (Exception e) {
System.out.println("wrong format");
System.exit(0);
}
}

private static void addCourse(String[] strs) {
try {
Course course = new Course();
course.name = strs[0];
course.nature = strs[1];
if (strs.length > 2) {
if (strs[1].equals("必修") && !strs[2].equals("考试")) {
System.out.println(strs[0] + " : course type & access mode mismatch");
}
course.examType = strs[2];
} else if (!course.nature.equals("必修")) {
System.out.println(strs[0] + " : course type & access mode mismatch");
System.exit(0);
}
courses.add(course);
} catch (Exception e) {
System.out.println("wrong format");
System.exit(0);
}
}
}

类图如下:

 

(1)

Main类,其中嵌套了一个内部类Course。以下是对代码的分析:

  1. Course类是一个简单的数据类,用于表示课程信息。它具有以下成员变量:

    • name:课程名称的字符串类型变量。
    • nature:课程性质(必修或选修)的字符串类型变量。
    • examType:考核方式(考试或考察)的字符串类型变量。
  2. Course类有两个构造方法:

    • 带有参数的构造方法:接受课程名称、课程性质和考核方式作为参数,并将其赋值给相应的成员变量。
    • 无参数的构造方法:创建一个空的Course对象。
  3. Course类实现了Comparable<Course>接口,通过重写compareTo方法,定义了课程对象之间的比较规则。

    • compareTo方法中,使用课程名称进行比较,并返回比较结果的整数值。使用o.name.compareTo(this.name)的方式,可以按照课程名称的字典顺序进行比较。

提供了一个基本的课程对象表示方式,并通过实现Comparable接口,允许课程对象之间进行比较操作,比较的依据是课程名称。在后续的代码中,可以更进一步利用Course对象进行排序、过滤等操作。

(2)

Grade类,用于表示学生的成绩信息。以下是对代码的分析:

  1. Grade类是一个简单的数据类,用于表示学生的成绩。它具有以下成员变量:

    • studentId:学号的字符串类型变量。
    • name:姓名的字符串类型变量。
    • courseName:课程名称的字符串类型变量。
    • usualScore:平时成绩的整数类型变量。
    • examScore:期末成绩的整数类型变量。
  2. Grade类有一个构造方法:

    • 带有参数的构造方法:接受学号、姓名、课程名称、平时成绩和期末成绩作为参数,并将其赋值给相应的成员变量。

这段代码提供了一个基本的学生成绩对象表示方式,包含学号、姓名、课程名称以及平时成绩和期末成绩。通过创建Grade对象,可以存储和获取学生的成绩信息。在后续的代码中,可以利用Grade对象进行成绩计算、排序等操作。

7-3 课程成绩统计程序-2

 类图如下

 

 

源码太长,逐类分析其中主要类
(1)

public class Main {

/**
* 学生类
*/
static class Student {
Integer studentId; // 学号

Integer classId; // 班级
String name; // 姓名

 

public Student(Integer studentId, Integer classId, String name) {
this.studentId = studentId;
this.classId = classId;
this.name = name;
}
}

其中定义了一个静态内部类 Student

 

    • Main 类是一个顶级类。
    • 在该类中,只定义了一个静态内部类 Student
  1. 静态内部类 Student

    • Student 类表示一个学生对象。
    • 它包含以下属性:
      • studentId:学号,使用 Integer 类型表示。
      • classId:班级,使用 Integer 类型表示。
      • name:姓名,使用 String 类型表示。
    • 构造方法 Student
      • Student 构造方法用于创建 Student 对象。
      • 构造方法接受三个参数:studentIdclassId 和 name,用于初始化对象的属性。

该代码片段中定义了一个简单的学生类 Student,其中包含了学生的基本信息。这个类可以被其他类使用,例如在一个学生管理系统中,可以实例化 Student 对象来表示学生,并操作学生对象的属性和行为。

(2)

static class Course implements Comparable<Course> {
String name; // 课程名称
String nature; // 课程性质(必修或选修)
String examType; // 考核方式(考试或考察)

public Course(String name, String nature, String examType) {
this.name = name;
this.nature = nature;
this.examType = examType;
}

@Override
public int compareTo(Course o) {
return o.name.compareTo(this.name);
}
}

  1. 静态内部类 Course

    • Course 类表示一个课程对象。
    • 它包含以下属性:
      • name:课程名称,使用 String 类型表示。
      • nature:课程性质,表示必修课或选修课,使用 String 类型表示。
      • examType:考核方式,表示考试或考察,使用 String 类型表示。
    • 构造方法 Course
      • Course 构造方法用于创建 Course 对象。
      • 构造方法接受三个参数:namenature 和 examType,用于初始化对象的属性。
  2. 接口 Comparable<Course>

    • Course 类实现了 Comparable 接口,并指定泛型类型为 Course
    • 通过实现 Comparable 接口,Course 类可以进行对象之间的比较和排序操作。
    • compareTo 方法:
      • compareTo 方法是 Comparable 接口中定义的方法,用于比较当前对象与指定对象的顺序。
      • 在这个实现中,根据课程名称进行比较,使用 name 属性进行比较并返回比较结果的整数值。
      • 通过返回 o.name.compareTo(this.name),实现了按照课程名称的降序进行排序。

该代码片段定义了一个课程类 Course,用于表示课程对象,并提供了比较和排序的功能。这样的设计可以方便地对课程对象进行排序,并根据课程名称进行查找和操作。

(3)

static class Grade {
String courseName; // 课程名称
Integer usualScore; // 平时成绩
Integer examScore; // 期末成绩
Integer experimentNumber; //实验次数
List<Integer> experimentScores; // 实验成绩列表
Integer total; // 总成绩

public Grade(String courseName, Integer usualScore, Integer examScore, Integer experimentNumber,Integer total) {
this.courseName = courseName;
this.usualScore = usualScore;
this.examScore = examScore;
this.experimentNumber = experimentNumber;
this.experimentScores = new ArrayList<>();
this.total = total;
}
}


/**
* 学号,学生
*/
private static Map<Integer, Student> students = new HashMap<>();
/**
* 课程名,课程
*/
private static Map<String, Course> courses = new HashMap<>();
/**
* 学号,成绩
*/
private static Map<Integer, List<Grade>> grades = new HashMap<>();
/**
* 学生平均分
*/
private static Map<Integer, Integer> studentAvgMap = new HashMap<>();
/**
* 课程各成绩均分
*/
private static Map<String, List<Grade>> courseAvgMap = new HashMap<>();
/**
* 班级学生
*/
private static Map<Integer, List<Student>> classStuMap = new HashMap<>();

/**
* 班级平均分
*/
private static Map<Integer, Integer> classAvgMap = new HashMap<>();

private static boolean courseNotExist = false;

private static boolean isNumeric(String str){
for(int i=str.length();--i>=0;){
int chr=str.charAt(i);
if(chr<48 || chr>57){
return false;
}
}
return true;
}

private static boolean isTwo(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String inputStr = scanner.nextLine();
while (!Objects.equals("end",inputStr)) {
String[] strs = inputStr.split(" ");
if (strs.length > 3) {
validAndPutGrade(strs);
} else {
addCourse(strs);
}
inputStr = scanner.nextLine();
}
listSort();
printStu();
printCourse();
printClass();
System.exit(0);
}

  1. 静态内部类 Grade

    • Grade 类表示一个成绩对象。
    • 它包含以下属性:
      • courseName:课程名称,使用 String 类型表示。
      • usualScore:平时成绩,使用 Integer 类型表示。
      • examScore:期末成绩,使用 Integer 类型表示。
      • experimentNumber:实验次数,使用 Integer 类型表示。
      • experimentScores:实验成绩列表,使用 List<Integer> 类型表示。
      • total:总成绩,使用 Integer 类型表示。
    • 构造方法 Grade
      • Grade 构造方法用于创建 Grade 对象。
      • 构造方法接受五个参数:courseNameusualScoreexamScoreexperimentNumber 和 total,用于初始化对象的属性。
      • 在构造方法中,还初始化了 experimentScores,将其实例化为一个空的 ArrayList
  2. 变量和集合:

    • students:表示学号与学生对象之间的映射关系,使用 Map<Integer, Student> 类型表示。
    • courses:表示课程名与课程对象之间的映射关系,使用 Map<String, Course> 类型表示。
    • grades:表示学号与成绩列表之间的映射关系,使用 Map<Integer, List<Grade>> 类型表示。
    • studentAvgMap:表示学生学号与平均分之间的映射关系,使用 Map<Integer, Integer> 类型表示。
    • courseAvgMap:表示课程名与成绩列表之间的映射关系,使用 Map<String, List<Grade>> 类型表示。
    • classStuMap:表示班级与学生列表之间的映射关系,使用 Map<Integer, List<Student>> 类型表示。
    • classAvgMap:表示班级与平均分之间的映射关系,使用 Map<Integer, Integer> 类型表示。
    • courseNotExist:表示课程是否不存在的标志,使用 boolean 类型表示。
  3. 辅助方法:

    • isNumeric 方法:用于判断一个字符串是否只包含数字。
    • isTwo 方法:用于判断一个字符串是否可以解析为一个整数。

这段代码似乎是一个学生管理系统的一部分,定义了表示成绩、学生、课程以及学生与成绩之间的映射关系的数据结构和方法。然而,缺少了关于学生类的定义和实现,无法完全理解整个系统的功能和运作方式。

(4)

public static void listSort() {
courses = courses.entrySet().stream()
.sorted(Map.Entry.comparingByValue(new Comparator<Course>() {
@Override
public int compare(Course o1, Course o2) {
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(o1.name, o2.name);
}
}))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
}

private static void printStu() {
studentAvgMap = studentAvgMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));

// 排序后
List<Integer> removeKeys = new ArrayList<>();
studentAvgMap.forEach((key, value) -> {
if(grades!=null && !grades.isEmpty()){
value = (int) Math.floor(grades.get(key).stream().mapToInt(s->s.total).average().orElse(0D));
studentAvgMap.put(key,value);
System.out.println("" + key + " " + students.get(key).name + " " + value);
}else{
removeKeys.add(key);
}
});

if(removeKeys!=null && !removeKeys.isEmpty()){
removeKeys.forEach(key -> {
System.out.println(""+ key + " " + students.get(key).name +" did not take any exams");
studentAvgMap.remove(key);
});
}
}

private static void printCourse() {

courses.forEach((name,course) ->{
boolean exist = false;
if (Objects.equals("必修",course.nature)) {
if (!Objects.equals("考试",course.examType)) {
exist = true;
}
}
else if (Objects.equals("选修",course.nature)) {
if (!Objects.equals("考试",course.examType) && !Objects.equals("考察",course.examType)) {
exist = true;
}
}
else if (Objects.equals("实验",course.nature)) {
if (!Objects.equals("实验",course.examType)) {
exist = true;
}
}
if(!exist){
List<Grade> grades = courseAvgMap.get(course.name);
if(grades!=null && !grades.isEmpty()){
if(Objects.equals("实验",course.examType)){
boolean isExist = grades.stream().anyMatch(grade -> grade.total <0);
if(isExist){
System.out.println(course.name + " has no grades yet");
}else{
int total = (int) Math.floor(grades.stream().mapToInt(grade ->grade.total.intValue()).average().orElse(0D));
System.out.println(course.name + " " + total);
}
}else{
int usualScoreTotal = (int) Math.floor(grades.stream().mapToInt(grade -> grade.usualScore==null? 0 : grade.usualScore.intValue()).average().orElse(0D));
int examScoreTotal = (int) Math.floor(grades.stream().mapToInt(grade ->grade.examScore.intValue()).average().orElse(0D));
int total = (int) Math.floor(grades.stream().mapToInt(grade ->grade.total.intValue()).average().orElse(0D));
String s = usualScoreTotal != 0 ? "" + usualScoreTotal + " " + examScoreTotal : "" + examScoreTotal;
System.out.println(course.name + " " + s + " " + total);
}

}else{
System.out.println(course.name + " has no grades yet");
}
}
});
}

主要包含了三个方法:listSort()printStu()printCourse()

listSort()方法使用了Java 8中的流式操作对courses进行排序,并使用Collectors.toMap()方法将结果收集到一个LinkedHashMap中。在排序过程中,使用了自定义的Comparator来比较Course对象的名称。Collator.getInstance(Locale.CHINA)返回一个根据中文排序规则进行比较的Collator实例,通过调用compare()方法比较o1.nameo2.name的值。

printStu()方法首先对studentAvgMap进行排序,使用Map.Entry.comparingByKey()方法按键进行排序。然后遍历studentAvgMap中的每个键值对,在grades不为空且非空的情况下,计算对应学生的成绩平均值,并更新studentAvgMap中对应的值。最后,遍历removeKeys集合,输出没有参加考试的学生信息,并从studentAvgMap中移除相应的键值对。

printCourse()方法遍历courses中的每个键值对,对于nature为"必修"且examType不为"考试"的课程,设置exist标志为true

(5)

private static void printCourse() {

courses.forEach((name,course) ->{
boolean exist = false;
if (Objects.equals("必修",course.nature)) {
if (!Objects.equals("考试",course.examType)) {
exist = true;
}
}
else if (Objects.equals("选修",course.nature)) {
if (!Objects.equals("考试",course.examType) && !Objects.equals("考察",course.examType)) {
exist = true;
}
}
else if (Objects.equals("实验",course.nature)) {
if (!Objects.equals("实验",course.examType)) {
exist = true;
}
}
if(!exist){
List<Grade> grades = courseAvgMap.get(course.name);
if(grades!=null && !grades.isEmpty()){
if(Objects.equals("实验",course.examType)){
boolean isExist = grades.stream().anyMatch(grade -> grade.total <0);
if(isExist){
System.out.println(course.name + " has no grades yet");
}else{
int total = (int) Math.floor(grades.stream().mapToInt(grade ->grade.total.intValue()).average().orElse(0D));
System.out.println(course.name + " " + total);
}
}else{
int usualScoreTotal = (int) Math.floor(grades.stream().mapToInt(grade -> grade.usualScore==null? 0 : grade.usualScore.intValue()).average().orElse(0D));
int examScoreTotal = (int) Math.floor(grades.stream().mapToInt(grade ->grade.examScore.intValue()).average().orElse(0D));
int total = (int) Math.floor(grades.stream().mapToInt(grade ->grade.total.intValue()).average().orElse(0D));
String s = usualScoreTotal != 0 ? "" + usualScoreTotal + " " + examScoreTotal : "" + examScoreTotal;
System.out.println(course.name + " " + s + " " + total);
}

}else{
System.out.println(course.name + " has no grades yet");
}
}
});
}

private static void printClass() {
classStuMap.keySet().stream().forEach(classId->{
if(studentAvgMap!=null && !studentAvgMap.isEmpty()){
List<Integer> avgTotalList = classStuMap.get(classId).stream().map(stu -> studentAvgMap.get(stu.studentId)).collect(Collectors.toList());
classAvgMap.put(classId,(int) Math.floor(avgTotalList.stream().mapToInt(Integer::intValue).average().orElse(0D)));
}else{
classAvgMap.put(classId,-1);
}
});
if(classAvgMap!=null && !classAvgMap.isEmpty()){
classAvgMap = classAvgMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
// 排序后
classAvgMap.forEach((key, value) -> {
if(value<0){
System.out.println("" +key + " has no grades yet");
}else{
System.out.println("" + key + " " + value);
}
});
}
}

 

}

以上代码是printCourse()方法的实现。这个方法通过遍历courses,处理每个课程的信息。

首先,对于每个课程,会根据其natureexamType的取值来判断是否符合条件,并设置exist标志。根据不同情况的条件判断可以得出以下结论:

  • 对于"必修"课程,如果examType不是"考试",则认为符合条件,设置existtrue
  • 对于"选修"课程,如果examType既不是"考试"也不是"考察",则认为符合条件,设置existtrue
  • 对于"实验"课程,如果examType不是"实验",则认为符合条件,设置existtrue

然后,检查exist的值,如果为false,说明课程不符合上述条件,需要对其成绩进行分析和输出。

在分析阶段,首先从courseAvgMap中获取与当前课程名称对应的成绩列表grades。如果grades不为空且非空,会根据examType的值进行不同的处理逻辑。

如果examType为"实验",会检查grades中是否存在total小于0的情况。如果有,输出课程名称加上特定信息表示该课程还没有成绩;否则,计算gradestotal的平均值,并向下取整为整数,输出课程名称和平均值。

对于其他类型的课程,分别计算gradesusualScoreexamScoretotal的平均值,并向下取整为整数,分别输出课程名称、平均usualScore和平均examScore

课程成绩统计程序-3

类图如下

 

 (1)

static class Course implements Comparable<Course> {
String name; // 课程名称
String nature; // 课程性质(必修或选修)
String examType; // 考核方式(考试或考察)
double[] weight;

public Course(String name, String nature, String examType,double[] weight) {
this.name = name;
this.nature = nature;
this.examType = examType;
this.weight = weight;
}
public Course(String name, String nature, String examType) {
this.name = name;
this.nature = nature;
this.examType = examType;
}

@Override
public int compareTo(Course o) {
return o.name.compareTo(this.name);
}
}

Course的类,该类实现了Comparable接口,用于比较课程对象的顺序。

Course类具有以下成员变量:

  • name:课程名称
  • nature:课程性质,可以是"必修"或"选修"
  • examType:考核方式,可以是"考试"或"考察"
  • weight:权重数组,用于存储不同考核方式的权重值,可选参数

Course类提供了以下构造方法:

  • Course(String name, String nature, String examType, double[] weight):带有课程名称、课程性质、考核方式和权重数组的构造方法。
  • Course(String name, String nature, String examType):带有课程名称、课程性质和考核方式的构造方法。

该类还重写了compareTo()方法,用于实现课程对象之间的比较。在该实现中,通过比较课程名称来确定对象的顺序。

总体而言,该Course类用于表示课程对象,并提供比较功能来支持排序操作。在实际应用中,可以根据需要对课程对象进行排序或其他操作。

(2)

static class Grade {
String courseName; // 课程名称
Integer usualScore; // 平时成绩
Integer examScore; // 期末成绩
Integer experimentNumber; //实验次数
List<Integer> experimentScores; // 实验成绩列表
Integer total; // 总成绩

public Grade(String courseName, Integer usualScore, Integer examScore, Integer experimentNumber,Integer total) {
this.courseName = courseName;
this.usualScore = usualScore;
this.examScore = examScore;
this.experimentNumber = experimentNumber;
this.experimentScores = new ArrayList<>();
this.total = total;
}
}


/**
* 学号,学生
*/
private static Map<Integer, Student> students = new HashMap<>();
/**
* 课程名,课程
*/
private static Map<String, Course> courses = new HashMap<>();
/**
* 学号,成绩
*/
private static Map<Integer, List<Grade>> grades = new HashMap<>();
/**
* 学生平均分
*/
private static Map<Integer, Integer> studentAvgMap = new HashMap<>();
/**
* 课程各成绩均分
*/
private static Map<String, List<Grade>> courseAvgMap = new HashMap<>();
/**
* 班级学生
*/
private static Map<Integer, List<Student>> classStuMap = new HashMap<>();

/**
* 班级平均分
*/
private static Map<Integer, Integer> classAvgMap = new HashMap<>();

private static boolean courseNotExist = false;

private static boolean isNumeric(String str){
for(int i=str.length();--i>=0;){
int chr=str.charAt(i);
if(chr<48 || chr>57){
return false;
}
}
return true;
}
public static boolean isDouble(String str){
if (str.charAt(0) != '0'){
return false;
}
return isNumeric(str.substring(2));
}

private static boolean isTwo(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String inputStr = scanner.nextLine();
while (!Objects.equals("end",inputStr)) {
String[] strs = inputStr.split(" ");
if(strs.length >1) {
if (strs[1].equals("考试") || strs[1].equals("考察") || strs[1].equals("实验")) {
addCourse(strs);
} else {
validAndPutGrade(strs);
}
}
inputStr = scanner.nextLine();
}
listSort();
printStu();
printCourse();
printClass();
System.exit(0);
}

Grade的类,用于表示课程的成绩。

Grade类具有以下成员变量:

  • courseName:课程名称
  • usualScore:平时成绩
  • examScore:期末成绩
  • experimentNumber:实验次数
  • experimentScores:实验成绩列表,使用List<Integer>来存储多次实验的成绩
  • total:总成绩

Grade类提供了以下构造方法:

  • Grade(String courseName, Integer usualScore, Integer examScore, Integer experimentNumber, Integer total):带有课程名称、平时成绩、期末成绩、实验次数和总成绩的构造方法。在构造方法内,将实验成绩列表初始化为一个空的ArrayList

以上代码的作用是用来存储一门课程的成绩信息,包括平时成绩、期末成绩、实验成绩等。通过创建Grade类的对象可以方便地管理和操作课程的成绩数据。

3踩坑心得

 对于测试点的输出总是显示格式错五

 还有就是明明和预期结果一样但还是过不了测试点

 

 

 

还有很多时候就是对样例所给的不清楚导致无法继续写

4、改进建议

(1)使用更具有可读性和可维护性的命名约定:在命名变量、方法和类时,使用清晰、具有描述性的名称,以增加代码的可读性和可理解性。使用驼峰命名或下划线命名法来命名变量和方法。
(2)引入封装原则:通过封装的方式将类的内部实现细节隐藏,提供公共方法来访问和操作数据,以增加代码的可维护性和灵活性。
(3)添加适当的注释:使用注释来解释代码的功能、目的和关键步骤,以帮助其他开发人员更好地理解代码。注释应该清晰、简洁、易于理解。
(4)使用合适的数据结构:根据具体需求和场景,选择合适的数据结构来存储和操作数据。例如,使用Map来存储学生信息,使用List来存储成绩列表等。
(5)引入异常处理机制:在代码中添加适当的异常处理,以捕获和处理可能发生的异常情况,增强代码的健壮性和可靠性。
(6)应用设计模式和最佳实践:根据实际需求,应用适当的设计模式和最佳实践,以提高代码的可扩展性、可维护性和可复用性。例如,使用单例模式——来创建全局唯一的对象,使用工厂模式来创建对象等。
(7)进行单元测试:编写单元测试用例来验证代码的正确性和可靠性。通过自动化测试框架运行这些测试用例,以确保代码在后续改进和重构过程中不会引入新的问题和错误。
(8)进行代码审查和重构:定期进行代码审查,识别潜在的改进和优化点。通过重构代码,优化数据结构、算法和特定功能的实现,以提高代码的性能、可读性和可

5总结

学到了以下几个方面的知识和见解:

编码规范:在编写代码时,遵循良好的编码规范和最佳实践是非常重要的。这包括使用有意义的变量和方法命名、遵循适当的代码组织结构、进行适当的注释等。

数据结构和算法:在解决问题和设计系统时,选择合适的数据结构和算法是关键。学习和理解各种数据结构和算法的特点、优势和应用场景,可以提高程序的效率和性能。

异常处理:了解如何在代码中使用适当的异常处理机制,可以增加代码的健壮性和可靠性。学习如何捕获和处理不同类型的异常,以及如何进行错误处理和错误恢复,有助于构建可靠的软件系统。

设计模式:学习常见的设计模式有助于提高代码的可扩展性和可维护性。了解各种设计模式的原理、应用场景和实现方式,可以在软件设计和开发中应用这些模式,提高代码的质量和可重用性。

但仍有一些方面需要进一步学习和研究:

深入学习特定的编程语言和技术框架:选择一门主流编程语言,并深入了解其特性、用法和最佳实践。此外,还可以学习和掌握相关的技术框架和库,以提高开发效率和代码质量。

算法和数据结构的进一步学习:继续学习和研究不同的数据结构和算法,并掌握它们的实现、性能分析和优化技巧。这将有助于解决更复杂的问题和提高代码的效率。

软件工程和系统设计:学习软件工程的基本原理和方法,包括需求分析、系统设计、软件测试和项目管理等。了解如何构建可扩展、可维护和可靠的软件系统,对于成为一名优秀的开发人员非常重要。

持续学习和实践:编程是一个不断学习和不断进步的过程。不断阅读相关书籍、参与在线课程、解决实际问题和与其他开发人员交流,都是提升自己技能的有效途径。保持好奇心和学习的热情,持续改进和实践,将帮助您成为更优秀的开发者。

总之,编程是一个广阔而不断进化的领域,拥有坚实的基础知识和持续学习的态度是成功的关键。不断学习和研究新的技术和概念,同时在实践中提升自己的实际编程能力,将帮助我在软件开发领域取得更大的成功。、

建议:就是大作业的测试点与题目的测试样例不对应,导致找错误要找好久,还不一定找得到,希望测试点可以对应了测试样例的顺序。如果可以对错误的测试点有所提示的话那可就泰酷辣。