import java.util.*;
import java.text.*;
class Calculate_grades {
int stu_all_grades(Data_storage data_storage,String num){//单个学生总课程平均分计算 返回一个分数 1)
int count =0;//这个学生有几门课
int sum = 0;
for (Map.Entry<String, Score> entry : data_storage.stu__st_cour.get(num).gradeMap.entrySet()) {
Score value = entry.getValue();
if(Integer.parseInt(value.total_scores)>=0) {
count++;
sum += Integer.parseInt(value.total_scores);
}
}
if(count!=0)
return sum/count;
else
return -100;//没有参加任何考试
}
int[] single_course_grades(Data_storage data_storage,String name){ //2) 课程名
int count = 0;
int[] aver_grade = new int[3];//0:平时成绩 1:期末考试 2:总分平均
for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//遍历选课类:num-选课类
StudentsAll_mes value = e.getValue();
for (Map.Entry<String, Score> entry : value.gradeMap.entrySet()) {//遍历选课类:course.name-Score
String key1 = entry.getKey();
Score value1 = entry.getValue();
if (key1.equals(name)) {
if(Integer.parseInt(value1.total_scores)>=0) {//总分为- 说明算成绩无效
count++;
aver_grade[2] += Integer.parseInt(value1.total_scores);
if (value1 instanceof Test_Score) {
if (Integer.parseInt(value1.total_scores) >= 0) {
aver_grade[0] += Integer.parseInt(((Test_Score) value1).normal_score);
aver_grade[1] += Integer.parseInt(((Test_Score) value1).end_score);
}
} else if (value1 instanceof Inspect_Score){
if (Integer.parseInt(value1.total_scores) >= 0) {
aver_grade[0] = -100;//不需要平时成绩
aver_grade[1] += Integer.parseInt(((Inspect_Score) value1).end_score);
}
}else if(value1 instanceof Lab_Score){
if(Integer.parseInt(value1.total_scores)>=0){
aver_grade[0] = -100;
aver_grade[1] += aver_grade[1] += Integer.parseInt(value1.total_scores);
}
}
}
}
}
}
if(count!=0) {
for (int i = 0; i < 3; i++) {
aver_grade[i] = aver_grade[i] / count;
}
}else {
for (int i = 0; i < 3; i++) {
aver_grade[i] = -100;
}
}
return aver_grade;
}
int Class_grades(Data_storage data_storage,String num){//3)
int sum = 0;
int count = 0;
for (Map.Entry<String, Student> mapEntry : data_storage.classes.get(num).students.entrySet()) {//班级号-Student类
Student value = mapEntry.getValue();//遍历这个班级的所有学生
for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//stu_num-选课类
String key1 = e.getKey();//遍历学生的选课类 学号
StudentsAll_mes value1 = e.getValue();
if (key1.equals(value.num)) {//选课类中 跟输入的学号一样
for (Map.Entry<String, Score> entry : value1.gradeMap.entrySet()) {//该num所有成绩遍历
Score gra = entry.getValue();
if(Integer.parseInt(gra.total_scores)>=0) {//有效才算
sum += Integer.parseInt(gra.total_scores);
count++;
}
}
}
}
}
if(count!=0)
return sum/count;
else
return -100;
}
void final_score(Data_storage data_storage,String num){//计算没门课的成绩 学号
data_storage.stu__st_cour.get(num).gradeMap.forEach((key,value)->{//学号 成绩
if(value instanceof Test_Score&&((Test_Score) value).normal_score.matches("\\d+")&&((Test_Score) value).end_score.matches("\\d+")) {
double tem = ((Test_Course) data_storage.courses.get(key)).normal_weight*Integer.parseInt(((Test_Score) value).normal_score);
double tem1 = ((Test_Course) data_storage.courses.get(key)).end_weight*Integer.parseInt(((Test_Score) value).end_score);
value.total_scores = String.valueOf((int)(tem+tem1));
}else if(value instanceof Inspect_Score&&((Inspect_Score) value).end_score.matches("\\d+")){
value.total_scores = ((Inspect_Score) value).end_score;
}else if(value instanceof Lab_Score&&((Lab_Score) value).lab_num.matches("\\d+")){
float sum = 0;
int i=0;
for (Integer score : ((Lab_Score) value).scores) {
sum+= score* ((Lab_Course) data_storage.courses.get(key)).weights.get(i);
i++;
}
value.total_scores = String.valueOf((int)sum);
}
});
}
}
class Class {
String num;
TreeMap<String, Student> students = new TreeMap<>(); //班级里的学生 学号 学生
Class(String num){
this.num = num;
}
}
class Course {
String type;
String test_way;
String name;
Course(String name,String type, String test_way){
this.type = type;
this.name = name;
this.test_way = test_way;
}
}
class Inspect_Course extends Course{
Inspect_Course(String name, String type, String test_way) {
super(name, type, test_way);
}
}
class Test_Course extends Course{
double normal_weight;
double end_weight;
Test_Course(String name, String type, String test_way,String normal_weight,String end_weight) {
super(name, type, test_way);
this.normal_weight = Float.parseFloat(normal_weight);
this.end_weight = Float.parseFloat(end_weight);
}
}
class Lab_Course extends Course{
int sub_scores_num;
ArrayList<Float> weights = new ArrayList<>();
Lab_Course(String name, String type, String test_way,String line) {
super(name, type, test_way);
String[] lines = line.split(" ");
sub_scores_num = Integer.parseInt(lines[3]);
for(int i=4;i<lines.length; i++){
weights.add(Float.parseFloat(lines[i]));
}
}
}
class Data_storage {
TreeMap<String , Course> courses;//课程 k:课程名 v:课程
TreeMap<String, Class> classes = new TreeMap<>();//班级 k:班级号V:班级
TreeMap<String, StudentsAll_mes> stu__st_cour;//选课类学生类结合 k:学号 v:选课类
InAndOut_put output = new InAndOut_put();
Data_storage(){
//学生和选课类结合
stu__st_cour = new TreeMap<>(Data_storage::compare);//重写排序
courses = new TreeMap<>(Data_storage::compare);
}
private static int compare(String o1, String o2) {
try {
Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
if (comparator.compare(o1, o2) < 0) {
return -1;
} else if (comparator.compare(o1, o2) > 0) {
return 1;
}
} catch (Exception ignored) {
}
return 0;
}
void setInspectCourses(String name, String type, String test_way){
if(!courses.containsKey(name)) {
courses.put(name, new Inspect_Course(name, type, test_way));
}
}
void setTestCourses(String name, String type, String test_way,String normal_weight, String end_weight){
if(!courses.containsKey(name)) {
courses.put(name, new Test_Course(name, type, test_way,normal_weight, end_weight));
}
}
void setLabCourses(String name, String type, String test_way,String line){
if(!courses.containsKey(name)) {
courses.put(name, new Lab_Course(name, type, test_way,line));
}
}
void setClasses(String num){
if(!classes.containsKey(num)) {
classes.put(num, new Class(num));
}
}
void setStudents(String clas_num, String name, String num){//班级号 姓名 学号
if(classes.containsKey(clas_num)){
if(!classes.get(clas_num).students.containsKey(num))
classes.get(clas_num).students.put(num,new Student(name,num));
}
}
void setStu__st_courAndMap(String num,String course,String normal_score,String end_score){//添加选课类 学生姓名 课程名称 分数
if(!stu__st_cour.containsKey(num)){
stu__st_cour.put(num,new StudentsAll_mes(num,course,normal_score,end_score));
}
else{
stu__st_cour.get(num).setGradeMap(course,normal_score,end_score);
}
}
void setStu__st_courAndMap(String num,String course,String end_score){
if(!stu__st_cour.containsKey(num)){
stu__st_cour.put(num,new StudentsAll_mes(num,course,end_score));
}
else{
stu__st_cour.get(num).setGradeMap(course,end_score);
}
}
void set_lab_grades(String stu_num,String course,String lab_num,String grades){
ArrayList<Integer> scores = new ArrayList<>();
String[] tem = grades.split(" ");
for(int i=3;i<tem.length;i++){
if(tem[i].matches("\\d+"))
scores.add(Integer.parseInt(tem[i]));
}
if(!stu__st_cour.containsKey(stu_num)){
StudentsAll_mes tem_stu_mes = new StudentsAll_mes();
tem_stu_mes.set_lab_stu_mes(stu_num,course,lab_num,scores);
stu__st_cour.put(stu_num,tem_stu_mes);
}else{
stu__st_cour.get(stu_num).set_lab_gradeMap(course,lab_num,scores);
}
}
}
class Input_Format {
String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修)\\s考试\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s选修\\s考察$";
String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s实验\\s实验\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){3,9}$";
String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4E00-\\u9FA5A-Za-z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){2,9}$";
boolean isEnd = true;//结束标志
String[] strings;
void inputProcessing(String line,Data_storage data_storage) {
lineProcessing(line);//分割
data_storage.output.add_input(line);//存储
if(line.matches(regex_c_inspect)){
data_storage.setInspectCourses(strings[0],strings[1],strings[2]);
}else if(line.matches(regex_c_lab)){
data_storage.setLabCourses(strings[0],strings[1],strings[2],line);
}else if(line.matches(regex_c_test)){
data_storage.setTestCourses(strings[0],strings[1],strings[2],strings[3],strings[4]);//成绩信息
} else if(line.matches(regex_CS)||line.matches(regex_lab)){
data_storage.setClasses(strings[0].substring(0,6));
data_storage.setStudents(strings[0].substring(0, 6), strings[1], strings[0]);//学生的添加
if (data_storage.courses.containsKey(strings[2])) {//课程里有这个课
if (data_storage.courses.get(strings[2]).type.equals("选修")) {//
if (data_storage.courses.get(strings[2]).test_way.equals("考试")&&strings.length == 5) {
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3], strings[4]);
}else if(data_storage.courses.get(strings[2]).test_way.equals("考察")&&strings.length==4){
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3]);
} else {
data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
}
} else if (data_storage.courses.get(strings[2]).type.equals("必修")) {//
if (strings.length == 5) {
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3],strings[4]);
} else {//无效
data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
}
} else if(data_storage.courses.get(strings[2]).type.equals("实验")){
if(strings.length == 3+((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num){
data_storage.set_lab_grades(strings[0],strings[2], String.valueOf(((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num),line);
}else{
data_storage.set_lab_grades(strings[0],strings[2],"num error","no access");
}
}
}else{
data_storage.setStu__st_courAndMap(strings[0], strings[2], "not exist");
}
}
}
void lineProcessing(String line){
strings = line.split(" ");
}
}
class Inspect_Score extends Score{
String end_score;
Inspect_Score(String end_score) {
this.end_score = end_score;
}
}
class Output_Format {
Calculate_grades calculate = new Calculate_grades();
String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((\\d{1,2})|(1-9?))\\s((\\d{1,2})|(1-9?))$";
String regex_c_test_e = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)$";
String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){1,10}$";
String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){1,20}$";
void outputProcessing(Data_storage data) {
data.classes.forEach((num,Class)-> Class.students.forEach((name, student)-> calculate.final_score(data,student.num)));
for(String i:data.output.input){
String[] tem = i.split(" ");
if(i.matches(regex_c_test_e)||i.matches(regex_c_test)||i.matches(regex_c_inspect)||i.matches(regex_c_lab)){
if(tem[1].equals("必修")&&(tem[2].equals("考察")||tem[2].equals("实验"))){
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}else if(tem[1].equals("实验")&&!tem[2].equals("实验")) {
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}else if(tem[1].equals("选修")&&tem[2].equals("实验")) {
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}
if(tem[1].equals("实验")&&tem[2].equals("实验")) {
if(tem.length-4>=4&&tem.length - 4<=9) {
if (Integer.parseInt(tem[3]) != tem.length - 4) {
data.output.add_output(tem[0] + " : number of scores does not match");
data.courses.remove(tem[0]);
continue;
}
float tem_weight = 0;
for (int j = 4; j < tem.length; j++) {
tem_weight += Float.parseFloat(tem[j]);
}
if (Math.abs(tem_weight - 1) > 0.0001) {
data.output.add_output(tem[0] + " : weight value error");
data.courses.remove(tem[0]);
continue;
}
}else{
try {
if (Integer.parseInt(tem[3]) != tem.length - 4) {
data.output.add_output(tem[0] + " : number of scores does not match");
data.courses.remove(tem[0]);
continue;
}
} catch (Exception ignored) {
}
}
}if((tem[1].equals("必修")||tem[1].equals("选修"))&&tem[2].equals("考试")){
if(tem.length-3==2) {
float tem_weight = Float.parseFloat(tem[3]) + Float.parseFloat(tem[4]);
if (Math.abs(tem_weight - 1) > 0.0001) {
data.output.add_output(tem[0] + " : weight value error");
data.courses.remove(tem[0]);
}
}
}
}else if(i.matches(regex_CS)||i.matches(regex_lab)) {
if(!data.courses.containsKey(tem[2])){//不存在
data.output.add_output(tem[2]+" does not exist");
data.stu__st_cour.get(tem[0]).gradeMap.remove(tem[2]);
}else{
if(data.courses.get(tem[2]).type.equals("必修") && tem.length!=5) {//必修 但是只有期末成绩
data.output.add_output(tem[0]+" "+tem[1]+" : access mode mismatch");
}else if(data.courses.get(tem[2]).type.equals("选修")) {
if ((data.courses.get(tem[2]).test_way.equals("考试") && tem.length != 5) ||
(data.courses.get(tem[2]).test_way.equals("考察") && tem.length != 4))
data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
}else if(data.courses.get(tem[2]).type.equals("实验")){
if(data.courses.get(tem[2]).test_way.equals("实验")&&(tem.length-3<4||tem.length-3>9||tem.length-3!=((Lab_Course) data.courses.get(tem[2])).sub_scores_num))
data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
}
}
}else if(!i.equals("end")){
data.output.add_output("wrong format");
}
}
data.classes.forEach((cla_num,Class1)->{//遍历所有班级
Class1.students.forEach((stu_num,student)->{
int tem=calculate.stu_all_grades(data,stu_num);
if(tem>=0)
data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+tem);
else
data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+"did not take any exams");
});
});
data.courses.forEach((key,value)-> {
int[] tem = calculate.single_course_grades(data, key);
if (tem[0] < 0 && tem[1] < 0 && tem[2] < 0) {//三个为- 则没成绩
data.output.add_output(key + " has no grades yet");
}else {
if (value.type.equals("选修") || value.type.equals("必修") || value.type.equals("实验")) {
data.output.add_output(key + " " + tem[2]);
}
}
});
data.classes.forEach((num,Class)->{
int tem = calculate.Class_grades(data,num);
if(tem>=0) {
data.output.add_output(num + " " + tem);
}else
data.output.add_output(num+" has no grades yet");
});
}
void output_all(Data_storage data){
data.output.output.forEach(System.out::println);
}
}
abstract class Score {
String total_scores = "-100";
}
class Student {
String name;
String num;
Student(String name, String num) {
this.name = name;
this.num = num;
}
}
class StudentsAll_mes {
String num;//学生
TreeMap<String,Score> gradeMap =new TreeMap<>();
StudentsAll_mes(String stu_name, String course, String normal_score,String test_score){
this.num = stu_name;
gradeMap.put(course,new Test_Score(normal_score,test_score));
}
StudentsAll_mes(String stu_name, String course, String test_score){
this.num = stu_name;
gradeMap.put(course,new Inspect_Score(test_score));
}
public StudentsAll_mes() {
}
void set_lab_stu_mes(String stu_num,String course,String lab_num,ArrayList<Integer> scores){
this.num = stu_num;
gradeMap.put(course,new Lab_Score(lab_num,scores));
}
void set_lab_gradeMap(String course,String lab_num,ArrayList<Integer> scores){
if(!gradeMap.containsKey(course))
gradeMap.put(course,new Lab_Score(lab_num,scores));
}
void setGradeMap(String course, String normal_score,String test_score){
if(!gradeMap.containsKey(course))
gradeMap.put(course, new Test_Score(normal_score,test_score));
}
void setGradeMap(String course,String test_score){
if(!gradeMap.containsKey(course))
gradeMap.put(course,new Inspect_Score(test_score));
}
}
class Test_Score extends Score{
String normal_score;
String end_score;
Test_Score(String normal_score,String end_score) {
this.normal_score = normal_score;
this.end_score = end_score;
}
}
class Lab_Score extends Score {
String lab_num;//试验次数
ArrayList<Integer> scores;
Lab_Score(String lab_num,ArrayList<Integer> scores){
this.lab_num = lab_num;
this.scores = scores;
}
}
class InAndOut_put {
List<String> output = new ArrayList<>();
List<String> input = new ArrayList<>();
void add_output(String out){
output.add(out);
}
void add_input(String out){
input.add(out);
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Input_Format inputFormat = new Input_Format();//输入
Output_Format outputFormat = new Output_Format();//输出
Data_storage data_storage = new Data_storage();
while (inputFormat.isEnd){
String inputLine = scanner.nextLine();
if(inputLine.equals("end")){
inputFormat.isEnd = false;
break;
}
inputFormat.inputProcessing(inputLine,data_storage);
}
outputFormat.outputProcessing(data_storage);
outputFormat.output_all(data_storage);
}
}
(3)踩坑心得
此题的难度适中,适合考察学生对面向对象设计原则和异常处理的理解。
在处理输入输出时,需要注意格式的要求,使用适当的分隔符进行分割。还要注意数组越界的问题,确保课程索引在合法范围内。
在解决问题时要选择合适的数据结构来存储和处理数据,例如使用列表和映射。
计算平均成绩时,需设计合适的算法处理课程成绩和权重,例如使用循环遍历计算总成绩。
编写代码时,要注意可读性和可维护性,使用合适的命名、注释和代码结构。可以考虑封装一些功能成函数,提高代码的可维护性。
(4)改进建议
在处理数据时,需要考虑使用合适的数据结构来存储和处理数据。例如,使用Set来存储班级信息,使用Map来存储学生和成绩的关系。这样可以更方便地进行数据的查找和操作。
Java 8引入了流式操作和Lambda表达式,可以借助它们来简化代码,提高代码的可读性。例如,可以使用stream()方法和filter()方法来过滤数据,使用map()方法来转换数据等。
在处理输入时需要考虑错误处理和异常处理。例如,当解析学生信息时,可以使用try-catch块来捕获可能产生的异常,如数组越界异常,并进行相应的处理。
在设计和实现功能时,遵循单一职责原则,确保每个类和方法只负责一项具体的功能。这样可以提高代码的可维护性和复用性。
编写适当的单元测试来验证代码的正确性是很重要的。可以使用JUnit等单元测试框架编写测试用例,并进行测试。这样可以确保代码在不同情况下的正确性。
为代码添加适当的注释和文档也是很重要的。注释可以解释代码的意图和实现细节,文档可以提供代码的使用方法和示例。
(5)总结
Java是一门广泛应用于软件开发的高级编程语言。通过学习Java,我获得了以下几方面的知识和技能:
1. 语法基础:掌握了Java的基本语法规则,了解了标识符、变量、数据类型、运算符、流程控制语句等基本概念。通过练习和实践,熟悉了Java的编写风格和命名规范。
2. 面向对象编程:学习了面向对象的思想和相关的概念,包括类、对象、封装、继承、多态等。掌握了如何使用类和对象来组织代码,提高代码的可重用性和可维护性。
3. 常用类库和API:了解并熟悉了Java的常用类库和API,如字符串处理、集合框架、I/O操作、异常处理等。学会了使用这些工具来简化开发过程,提高效率。
4. 多线程编程:学习了Java多线程编程的基本概念和技巧,包括线程的创建、同步与互斥、线程池等。了解了如何使用多线程来提高程序的性能和响应性。
5. 异常处理:学习了如何设计和处理异常,包括如何捕获异常、抛出异常以及异常处理的机制。通过实践,提升了代码的健壮性和可靠性。
6. 输入输出操作:掌握了Java中的输入输出操作,包括文件读写、网络通信等。了解了如何使用Java提供的输入输出流来实现数据的读写和传输。
7. 开发工具和环境:熟悉了常用的开发工具和环境,如Eclipse、IntelliJ IDEA等。了解了如何配置和使用开发工具,提高开发效率。
通过Java的学习,我不仅获得了编程的基础知识和技能,还培养了分析问题、解决问题和合作开发的能力。Java作为一门广泛应用的编程语言,它的应用领域非常广泛,为我未来的学习和工作提供了坚实的基础。我会继续深入学习Java,并将它应用于实际的项目开发中。