BLOG-1-7213

发布时间 2023-10-07 19:17:13作者: 月如心梦满枝

(1)前言:主要用于完成学校的互评作业大家懂的都懂,前三次的题目集,大概囊括了最基础的输入输出、类的创建;字符串的各种操作(定位某个特点字符在字符串中的下标、提取某段需要的子字符串、对于某个字符或某个子字符串的格式判断等等)、类的交互、函数的创建与使用以及正则表达式的运用等等。关于难度方面,第一次作业的8个题难度平均较低,属于基础知识点的运用考察,第二次则开始提高难度,且幅度较大,第三次在第二次的基础上继续提高了难度以及复杂性,其主要提高的是复杂性和繁琐度,致使总体解题难度上升幅度较大。

(2)设计与分析:

第一次作业 7-5 游戏角色选择

7-5 游戏角色选择
分数 14
作者 蔡轲
单位 南昌航空大学

一款网游中包括4个种族:人类、精灵、兽人、暗精灵,每个种族包含三种角色:战士、法师、射手。玩家新建人物时需要选择种族和角色。请编写角色选择程序。

输入格式:

两个整数:游戏种族、角色的选项,以空格分隔。例如:1 2。
种族选项设定为:1、人类 2、精灵 3、兽人 4、暗精灵
角色选项设定为:1、战士 2、法师 3、射手

输出格式:

所选择的种族、角色的名称,以空格分隔。例如:人类 法师
若输入数值超出选项范围,输出“Wrong Format”

输入样例1:

在这里给出一组输入。例如:

1 2

输出样例1:

在这里给出相应的输出。例如:

人类 法师

输入样例2:

在这里给出一组输入。例如:

1 6

输出样例2:

在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
此题主要多次用到switch case 函数
  1. 在主函数public static void main(String[] args)中,首先使用Scanner类创建一个Scanner对象sc,用于获取用户的输入。

  2. 使用sc.nextInt()方法依次读取两个整数nm,分别表示种族选项和角色选项。

  3. 使用switch语句对n进行判断,根据不同的种族选项进入不同的case分支。

  4. 在每个case分支中,再使用switch语句对m进行判断,根据不同的角色选项输出相应的种族和角色名称。

  5. 如果输入的选项超出了范围,会执行default分支,输出"Wrong Format"表示格式错误。

  6. 代码执行结束后,程序退出。

通过嵌套的switch语句实现了角色选择的功能,根据不同的种族和角色选项输出相应的名称。

题目集2 7-1

7-1 成绩计算-1-类、数组的基本运用
分数 10
作者 蔡轲
单位 南昌航空大学

创建学生类,包含

属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)

方法:计算总分、计算平均分

输入5个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

浮点数保留小数的相关知识可参考:
https://blog.csdn.net/huaishuming/article/details/17752365


注意:未用学生类对象封装数据的,本题计0分

输入格式:

5个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+语文成绩+英文空格+数学成绩+英文空格+物理成绩
例如:
22201311 张琳 80 80 80

22201312 黄昊 66 82 81

22201313 李少辰 77 76 80

22201314 袁婷 62 79 90

22201315 朱哲一 74 98 94

输出格式:

5个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分

例如:

22201311 张琳 240 80.00

22201312 黄昊 229 76.33

22201313 李少辰 233 77.67

22201314 袁婷 231 77.00

22201315 朱哲一 266 88.67

输入样例:

在这里给出一组输入。例如:

22201311 张琳 80 80 80
22201312 黄昊 66 82 81
22201313 李少辰 77 76 80
22201314 袁婷 62 79 90
22201315 朱哲一 74 98 94
 

输出样例:

在这里给出相应的输出。例如:

22201311 张琳 240 80.00
22201312 黄昊 229 76.33
22201313 李少辰 233 77.67
22201314 袁婷 231 77.00
22201315 朱哲一 266 88.67

代码用于统计五个学生的中、数、物科目成绩,并输出每个学生的总分和平均分。

  1. 定义了一个名为Student的类,其中包含学生的学号、姓名、语文、数学、物理成绩以及计算总分和平均分的方法。

  2. 在主函数中,定义了一个名为studentsList类型变量,用于存储五个学生的信息。

  3. 使用Scanner类创建一个Scanner对象scanner从控制台读取五个学生的信息,并将其转化为Student类型的对象,存储进students列表中。

  4. 遍历students列表,对于列表中的每个Student对象,调用其方法计算总分和平均分,并按照指定格式输出:学号、姓名、总分、平均分。

  5. 输出结果后程序结束。

通过定义Student类实现了学生信息的封装和计算,使得代码结构更为清晰,并且容易扩展和维护。使用列表来存储多个学生的信息,避免了多个变量之间的混乱,也便于对学生信息进行批量处理。

原代码如下:


import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Student {
private String studentId;
private String name;
private int chineseScore;
private int mathScore;
private int physicsScore;

public Student(String studentId, String name, int chineseScore, int mathScore, int physicsScore) {
this.studentId = studentId;
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.physicsScore = physicsScore;
}

public String getStudentId() {
return studentId;
}

public String getName() {
return name;
}

public int calculateTotalScore() {
return chineseScore + mathScore + physicsScore;
}

public double calculateAverageScore() {
int totalScore = calculateTotalScore();
return (double) Math.round(totalScore * 100 / 3.0) / 100; // 保留两位小数
}
}

public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
String studentInfo = scanner.nextLine();
String[] infoArray = studentInfo.split(" ");

if (infoArray.length == 5) {
String studentId = infoArray[0];
String name = infoArray[1];
int chineseScore = Integer.parseInt(infoArray[2]);
int mathScore = Integer.parseInt(infoArray[3]);
int physicsScore = Integer.parseInt(infoArray[4]);

Student student = new Student(studentId, name, chineseScore, mathScore, physicsScore);
students.add(student);
} else {
Student student = new Student("", "", 0, 0, 0);
students.add(student);
}
}

for (Student student : students) {
int totalScore = student.calculateTotalScore();
double averageScore = student.calculateAverageScore();
System.out.printf("%s %s %d %.2f%n", student.getStudentId(), student.getName(), totalScore, averageScore);
}
}
}

 
题目集2 7-2
7-2 成绩计算-2-关联类
分数 10
作者 蔡轲
单位 南昌航空大学

创建成绩类,包含:

属性:平时成绩(int)、期末成绩(int)

方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)

创建学生类,包含:

属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)

方法:计算总分、计算平均分

输入3个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365


注意:未用学生类对象封装数据的,本题计0分

输入格式:

依次输入3个学生的每门课成绩,每个学生成绩信息格式:

学号+英文空格+姓名+英文空格+课程名+英文空格+平时成绩+英文空格+期末成绩
注:3个学生的课程顺序可能会不一致

例如:
22201311 张琳 语文 70 80

22201311 张琳 数学 85 89

22201311 张琳 物理 75 83

22201312 黄昊 语文 66 78

22201312 黄昊 数学 76 82

22201312 黄昊 物理 83 82

22201313 李少辰 语文 86 76

22201313 李少辰 数学 78 76

22201313 李少辰 物理 87 76

输出格式:

3个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分

例如:


22201311 张琳 242 80.67

22201312 黄昊 234 78.00

22201313 李少辰 236 78.67

输入样例:

在这里给出一组输入。例如:

22201311 张琳 语文 70 80
22201311 张琳 数学 85 89
22201311 张琳 物理 75 83
22201312 黄昊 语文 66 78
22201312 黄昊 数学 76 82
22201312 黄昊 物理 83 82
22201313 李少辰 语文 86 76
22201313 李少辰 数学 78 76
22201313 李少辰 物理 87 76

输出样例:

在这里给出相应的输出。例如:

22201311 张琳 242 76.67 84.00 80.67
22201312 黄昊 234 75.00 80.67 78.00
22201313 李少辰 236 83.67 76.00 78.67

这段代码是一个学生成绩管理系统,可以输入学生的信息和课程成绩,然后计算总成绩和平均成绩,并输出结果。

首先,在Score类中定义了一个构造函数和一些getter和setter方法来设置和获取平时成绩和期末成绩。还有一个calculateTotalScore()方法,通过加权计算得到课程的最终成绩。

接下来,在Student类中定义了学生的基本信息和各科成绩,通过setScore()方法来设置每门科目的成绩。calculateTotalScore()方法用来计算学生的总成绩,calculateAverageScore()方法用来计算学生的平均成绩。

calculatepinshiAverageScore()方法和calculateqimoAverageScore()方法分别用来计算学生的平时成绩和期末成绩的平均值。print()方法用来输出学生的信息和成绩。

最后,在Main类的main方法中使用Scanner类来输入学生信息和成绩。通过循环遍历输入的学生信息,并通过判断学生是否存在来更新学生的成绩或创建新的学生对象。最后,再通过循环遍历输出学生的信息和成绩。

通过封装和继承的方式建立了Score和Student类,并使用了数组来存储多个学生对象,实现了学生成绩的管理和输出。

 

原码如下:

import java.util.*;
import java.text.DecimalFormat;
class Score {
private int pinshiScore;
private int qimoScore;

public Score(int pinshiScore, int qimoScore) {
this.pinshiScore = pinshiScore;
this.qimoScore = qimoScore;
}
public void setPinshiScore(){
pinshiScore = pinshiScore;
}
public void setQimoScore(){
qimoScore = qimoScore;
}
public int getPinshiScore(){
return this.pinshiScore;
}
public int getQimoScore(){
return this.qimoScore;
}

public int calculateTotalScore() {//计算课程成绩
return (int) (pinshiScore * 0.4 + qimoScore * 0.6);
}
}

class Student {
String studentId;
String name;
Score chineseScore;
Score mathScore;
Score physicsScore;

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

public void setScore(String course, int pinshiScore, int qimoScore) {//得到课程成绩
switch (course) {
case "语文":
chineseScore = new Score(pinshiScore, qimoScore);
break;
case "数学":
mathScore = new Score(pinshiScore, qimoScore);
break;
case "物理":
physicsScore = new Score(pinshiScore, qimoScore);
break;
default:
break;
}
}

 

public int calculateTotalScore() {//计算总成绩
int totalScore = 0;
totalScore += chineseScore.calculateTotalScore();
totalScore += mathScore.calculateTotalScore();
totalScore += physicsScore.calculateTotalScore();
return totalScore;

}

public double calculateAverageScore() {
int totalScore = calculateTotalScore();
return (double) totalScore / 3;
}
public double calculatepinshiAverageScore(){
int totalScore = 0;
totalScore += chineseScore.getPinshiScore();
totalScore += mathScore.getPinshiScore();
totalScore += physicsScore.getPinshiScore();
return (double) totalScore / 3;
}
public double calculateqimoAverageScore(){
int totalScore = 0;
totalScore += chineseScore.getQimoScore();
totalScore += mathScore.getQimoScore();
totalScore += physicsScore.getQimoScore();
return (double) totalScore / 3;
}

public void print() {//输出
int totalScore = calculateTotalScore();
double averageScore = calculateAverageScore();
double averagepinshiScore = calculatepinshiAverageScore();
double averageqimoScore = calculateqimoAverageScore();
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(studentId + " " + name + " " + totalScore + " " + df.format(averagepinshiScore)+ " " + df.format(averageqimoScore)+ " " + df.format(averageScore));
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Student[] students = new Student[3];

for (int i = 0; i < 9; i++) {
String input = scanner.nextLine();
String[] tokens = input.split(" ");
String studentId = tokens[0];
String name = tokens[1];
String course = tokens[2];
int pinshiScore = Integer.parseInt(tokens[3]);
int qimoScore = Integer.parseInt(tokens[4]);

boolean studentExists = false;
for (int j = 0; j < 3; j++) {
if (students[j] != null && students[j].studentId.equals(studentId)) {
students[j].setScore(course, pinshiScore, qimoScore);
studentExists = true;
break;
}
}

if (!studentExists) {
for (int j = 0; j < 3; j++) {
if (students[j] == null) {
students[j] = new Student(studentId, name);
students[j].setScore(course, pinshiScore, qimoScore);
break;
}
}
}
}
for (Student student : students) {
if (student != null) {
student.print();
}
}
}
}

 

菜单计价题
7-7 菜单计价程序-1
分数 30
作者 蔡轲
单位 南昌航空大学

某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9

设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}

点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}

订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}

输入格式:

每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。

输出格式:

订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 2
西红柿炒蛋 3
end

输出样例:

在这里给出相应的输出。例如:

48

输入样例1:

订单中包含不存在的菜品记录。例如:

麻婆豆腐 2
炒脆肚 2
西红柿炒蛋 3
end

输出样例1:

在这里给出相应的输出。例如:

炒脆肚 does not exist
48

一开始打算使用面向对象的思想来设计程序,使用菜品类、菜谱类、点菜记录类、订单类四个类来组织程序。


首先定义菜品类Dish,包含对应菜品上的信息,如名称和单价,以及计算菜品价格的方法。


然后定义菜谱类Menu,将所有菜品的信息保存在一个菜品数组中,还需要提供根据菜名查找菜品信息的方法。


接下来是点菜记录类Record,包含了一道菜品记录(即菜品和份额),还需提供计价的方法。


最后定义订单类Order,包含了多道菜品记录,提供了添加一道菜品记录到订单的方法,还需提供计算订单总价的方法。


需要注意的地方:当输入的菜名不在菜单中时,输出提示“** does not exist”,菜名为输入的菜名。菜品价格要按照题目要求进行计算。

最后的设计如下

  1. Dish类:表示菜品,包含菜品名称和单价属性,并提供了计算指定份数的菜品价格的方法。

  2. Menu类:表示菜单,包含了菜品数组,提供了根据菜名查找菜品信息的方法。

  3. Record类:表示一道菜品的点菜记录,包含了菜品和份额属性,并提供了计算点菜记录价格的方法。

  4. Order类:表示订单,包含了多个点菜记录,提供了添加一道菜品记录和计算订单总价的方法。

  5. MenuSystem类:用来初始化菜单,将所有菜品信息保存在菜单对象中。

  6. Main类:主程序入口,通过用户输入点菜信息,调用Order类的方法进行记录和计算总价。

这段代码使用了面向对象的设计思想,将功能模块分成不同的类,并且通过类之间的关联和调用完成相应的功能。每个类都承担了特定的责任,增强了代码的可读性和可维护性。

在Main类的main方法中,通过Scanner获取用户输入的点菜信息,然后调用Order类的addARecord方法将点菜记录添加到订单中。如果菜名不存在,在控制台输出相应的提示信息。最后调用Order类的getTotalPrice方法计算订单的总价,并输出到控制台。


原码:


import java.util.Scanner;


class Dish {
private String name;
private int unitPrice;


public Dish(String name, int unitPrice) {
this.name = name;
this.unitPrice = unitPrice;
}


public String getName() {
return name;
}


public int getUnitPrice() {
return unitPrice;
}


public int getPrice(int portion) {
if (portion == 1) {
return unitPrice;
} else if (portion == 2) {
return Math.round(unitPrice * 1.5f);
} else if (portion == 3) {
return unitPrice * 2;
} else {
return -1;
}
}
}


class Menu {
private Dish[] dishes;


public Menu(Dish[] dishes) {
this.dishes = dishes;
}


public Dish searchDish(String dishName) {
for (Dish dish : dishes) {
if (dish.getName().equals(dishName)) {
return dish;
}
}
return null;
}
}


class Record {
private Dish dish;
private int portion;


public Record(Dish dish, int portion) {
this.dish = dish;
this.portion = portion;
}


public int getPrice() {
if (dish == null) {
return -1;
}
return dish.getPrice(portion);
}
}


class Order {
private Record[] records;


public Order() {
records = new Record[10];
}


public int getTotalPrice() {
int totalPrice = 0;
boolean hasInvalidDish = false;
for (Record record : records) {
if (record != null) {
int price = record.getPrice();
if (price != -1) {
totalPrice += price;
} else {
hasInvalidDish = true;
}
}
}
if (hasInvalidDish) {
return -1;
}
return totalPrice;
}


public Record addARecord(String dishName, int portion) {
Dish dish = MenuSystem.menu.searchDish(dishName);
if (dish == null) {
return null;
}
Record record = new Record(dish, portion);
for (int i = 0; i < records.length; i++) {
if (records[i] == null) {
records[i] = record;
break;
}
}
return record;
}
}


class MenuSystem {
public static Menu menu;


static {
Dish[] dishes = {
new Dish("西红柿炒蛋", 15),
new Dish("清炒土豆丝", 12),
new Dish("麻婆豆腐", 12),
new Dish("油淋生菜", 9)
};
menu = new Menu(dishes);
}
}


public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Order order = new Order();


while (sc.hasNextLine()) {
String line = sc.nextLine().trim();
if (line.equals("end")) {
break;
}


String[] tokens = line.split("\\s+");
if (tokens.length != 2) {
continue;
}


String dishName = tokens[0];
int portion = Integer.parseInt(tokens[1]);


Record record = order.addARecord(dishName, portion);
if (record == null) {
System.out.println(dishName + " does not exist");
}
}


int totalPrice = order.getTotalPrice();
System.out.println(totalPrice);
}
}

题集3 7-2
7-2 课程成绩统计程序-1
分数 65

作者 蔡轲
单位 南昌航空大学

某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃

参考类图:


image.png

输入样例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

  1. 定义课程类Course,包含课程名称、课程性质和考核方式三个属性。
  2. 定义学生类Student,包含学号、姓名和成绩列表三个属性,成绩列表用于存储学生在各门课程的成绩。
  3. 定义班级类Class,包含班级号和学生列表两个属性,学生列表用于存储班级内的所有学生信息。
  4. 定义成绩统计类GradeStatistics,包含课程列表和班级列表两个属性,课程列表用于存储所有的课程信息,班级列表用于存储所有班级的信息。
  5. 在GradeStatistics类中定义以下方法:
    • addCourse(course_info):添加课程信息到课程列表中。
    • addStudentCourse(grade_info):将学生的课程成绩信息添加到班级列表中对应的学生对象中。
    • calculateAverage(): 计算并输出学生所有课程总成绩的平均分,按学号由低到高排序输出。
    • calculateCourseAverage(): 计算并输出每门课程的平时成绩平均分、期末考试平均分和总成绩平均分,按课程名称的字符顺序输出。
    • calculateClassAverage(): 计算并输出班级所有课程总成绩平均分,按班级号由低到高排序输出。

一直到最后依旧存在一些问题没有解决,无法通过一些测试点
源码

import java.util.*;


class Course {
private String name; // 课程名称
private String nature; // 课程性质
private String assessment; // 考核方式


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


public String getName() {
return name;
}


public String getNature() {
return nature;
}


public String getAssessment() {
return assessment;
}
}


class Grade {
private String studentId; // 学号
private String name; // 姓名
private String courseName; // 课程名称
private int regularGrade; // 平时成绩
private int finalGrade; // 期末成绩


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


public String getStudentId() {
return studentId;
}


public String getName() {
return name;
}


public String getCourseName() {
return courseName;
}


public int getRegularGrade() {
return regularGrade;
}


public int getFinalGrade() {
return finalGrade;
}
}


public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<Course> courses = new ArrayList<>();
List<Grade> grades = new ArrayList<>();
String input;


while (!(input = scanner.nextLine().trim()).equals("end")) {
String[] tokens = input.split("\\s+");
if (tokens.length == 1 && tokens[0].isEmpty()) {
continue;
}


if (tokens.length != 3) {
System.out.println("wrong format");
return;
}


String courseName = tokens[0];
String nature = tokens[1];
String assessment = tokens[2];


Course course = new Course(courseName, nature, assessment);
courses.add(course);
}


while (scanner.hasNextLine()) {
input = scanner.nextLine().trim();
if (input.isEmpty()) {
continue;
}


String[] tokens = input.split("\\s+");
if (tokens.length != 6 && tokens.length != 5) {
System.out.println("wrong format");
return;
}


String studentId = tokens[0];
String name = tokens[1];
String courseName = tokens[2];
int regularGrade = -1;
int finalGrade = -1;


try {
if (tokens.length == 6) {
regularGrade = Integer.parseInt(tokens[3]);
finalGrade = Integer.parseInt(tokens[4]);
}
else {
finalGrade = Integer.parseInt(tokens[3]);
}
} catch (NumberFormatException e) {
System.out.println("wrong format");
return;
}


Grade grade = new Grade(studentId, name, courseName, regularGrade, finalGrade);
grades.add(grade);
}


Map<String, List<Grade>> gradeMap = new HashMap<>();
Map<String, Double> averageGradeMap = new HashMap<>();
Map<String, Double> regularAverageMap = new HashMap<>();
Map<String, Double> finalAverageMap = new HashMap<>();
Map<String, Integer> totalCountMap = new HashMap<>();
Set<String> classNames = new HashSet<>();


for (Grade grade : grades) {
List<Grade> classGrades = gradeMap.getOrDefault(grade.getStudentId().substring(0, 6), new ArrayList<>());
classGrades.add(grade);
gradeMap.put(grade.getStudentId().substring(0, 6), classGrades);


double totalGrade = grade.getRegularGrade() * 0.3 + grade.getFinalGrade() * 0.7;


averageGradeMap.put(grade.getStudentId(), averageGradeMap.getOrDefault(grade.getStudentId(), 0.0) + totalGrade);
regularAverageMap.put(grade.getCourseName(), regularAverageMap.getOrDefault(grade.getCourseName(), 0.0) + grade.getRegularGrade());
finalAverageMap.put(grade.getCourseName(), finalAverageMap.getOrDefault(grade.getCourseName(), 0.0) + grade.getFinalGrade());


totalCountMap.put(grade.getCourseName(), totalCountMap.getOrDefault(grade.getCourseName(), 0) + 1);
classNames.add(grade.getStudentId().substring(0, 6));
}


List<String> sortedClassNames = new ArrayList<>(classNames);
Collections.sort(sortedClassNames);


for (String className : sortedClassNames) {
double totalGrade = 0;
int count = 0;


List<Grade> classGrades = gradeMap.get(className);
Collections.sort(classGrades, Comparator.comparing(Grade::getStudentId));


for (Grade grade : classGrades) {
System.out.println(grade.getStudentId() + " " + grade.getName() + " " + (int)(averageGradeMap.get(grade.getStudentId()) / totalCountMap.size()));
totalGrade += averageGradeMap.get(grade.getStudentId());
count++;
}


if (count == 0) {
System.out.println(className + " has no grades yet");
} else {
System.out.println(className + " " + (int)(totalGrade / count));
}
}


List<String> courseNames = new ArrayList<>();
for (Course course : courses) {
courseNames.add(course.getName());
}
Collections.sort(courseNames);


for (String courseName : courseNames) {
double regularAverage = regularAverageMap.getOrDefault(courseName, 0.0) / totalCountMap.getOrDefault(courseName, 0);
double finalAverage = finalAverageMap.getOrDefault(courseName, 0.0) / totalCountMap.getOrDefault(courseName, 0);


System.out.println(courseName + " " + (int)regularAverage + " " + (int)finalAverage + " " +
(int)((regularAverage * 0.3 + finalAverage * 0.7) / totalCountMap.getOrDefault(courseName, 0)));
}
}
}


(3)采坑心得:

在第一次作业中其实各方面的知识运用都还是比较基础的考察,各题目也不需要很多面向对象的设计思维,面向过程的编程思维便可解决。除去一些奇怪的测试点可能会卡住,总体而言只要花点时间仔细一点就能过。

第二、三次作业的难度显著上升,开始慢慢出现短时间内解决不了的问题。一些体会:

别怕犯错:编程的过程中难免会犯错,这是很正常的。重要的是不要害怕犯错,要从错误中学习并找到解决问题的方法。

理论与实践相结合:学习Java不仅要掌握理论知识,还要进行实践。尝试自己写一些简单的代码,并进行调试和测试,通过实际操作加深对理论知识的理解。

多做练习:编程语言的学习需要不断地练习和实践。可以通过做一些小项目或者刷一些编程题来提高自己的编程能力。

加入社区和交流:参加一些Java程序员的社群,例如论坛、技术交流群等,与其他人交流学习经验和问题解决方法。

 

(4)总结:
截至目前的三次作业,难度逐渐提高,复杂性也愈来愈高,对于面向对象程序设计思维要求也愈发增大。不过通过这三个礼拜的“折磨”也让我对Java的语法更加熟悉,也更加习惯、熟练面向对象的设计思维。