首页 > 编程语言 >课程成绩统计程序1-3

课程成绩统计程序1-3

时间:2023-06-23 19:33:56浏览次数:53  
标签:String 课程 程序 num output score 成绩 data tem

课程成绩统计程序系列分析

博客采取总——分模式


总体分析:

1.最终设计类图:
image

2.最终设计圈复杂度:
image
image
3.最终设计代码:

点击查看代码
import java.util.*;
import java.text.Collator;
import java.util.TreeMap;
public class Main {
    public static void main(String[] args) {
        Scanner scn = 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 = scn.nextLine();
            if(inputLine.equals("end")){
                inputFormat.isEnd = false;
                break;
            }
            inputFormat.inputProcessing(inputLine,data_storage);
        }
        outputFormat.outputProcessing(data_storage);
        outputFormat.output_all(data_storage);
    }
}
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(((Lab_Score) 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+")){
                int count = Integer.parseInt(((Lab_Score) value).lab_num);
                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 = -100;
    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<>(new Comparator<String>(){//学生和选课类结合
            @Override
            public 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 e) {
                }
                return 0;
            }
        });//重写排序
        courses = new TreeMap<>(new Comparator<String>() {
            @Override
            public 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 e) {
                }
                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 = "-100";
    Inspect_Score(String end_score) {
        this.end_score = end_score;
    }
}
class Output_Format {
    Calculate_grades calculate = new Calculate_grades();
    /*String regex_c_test_S = "^[a-zA-Z\\u4e00-\\u9fa5\\s]{1,10}\\s(必修|选修)\\s考试\\s\\d.\\d\\s\\d.\\d$";
    String regex_c_inspect_S = "[a-zA-Z0-9\\u4e00-\\u9fa5]{1,10}\\s选修\\s考察$";
    String regex_c_lab_S = "^[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s实验\\s实验\\s[1-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){1,10}$";*/
    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 {
                            int temp = Integer.parseInt(tem[3]);
                            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");
                        /*if(data.courses.get(tem[2]).test_way.equals("实验")&&(Integer.parseInt(tem[3])<4||Integer.parseInt(tem[3])>9)) {
                            data.output.add_output("wrong format");
                        }*/
                    }
                }
            }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="-100";
    String end_score="-100";
    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 = new ArrayList<>();
    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);
    }
}

4.最终代码分析:
可以从图中看到代码的平均圈复杂度较高。这是由于在学习了面向对象设计的几个原则后,我想将类的单一职责原则用上去。所以每一段输出,我几乎都要进行很多循环和遍历。导致较于之前平均圈复杂度高。其次在成绩数据储存里,选课类和和学号,成绩这三者的储存,我设计的很奇怪。在遍历算成绩的时候很别扭,选课类这一类设计的初衷是解班级 分数,学生这三个类的耦合。但是储存起来应该有更好的方法。这是一不好的地方。但总体能过全部测试点。也有冗余类,比如上述代码中的InAndOut_put类,实际作用是储存输出信息,初衷是储存错误信息。但是输出顺序掌控不好,我也没有进行重新的设计和删除。

5.难度分析:
整体题目难度不大,但开始第一次根据已有类图进行设计,给我造成较大的阻力。道理我都懂,选课类是为了解耦合。但是实际数据存储,让我有点为难,不知从何下手,经过很多次的修改。还有输出顺序方面。经过好几次题目的重新阅读才最终理清楚。

单次分析

  1. 课程成绩统计-1
    类设计:
    1)选课类
点击查看代码
class ChooseClass {
    String num;//学生
    TreeMap<String,Score> gradeMap =new TreeMap<>();
    ChooseClass(String stu_name, String course, String normal_score, String test_score){
        this.num = stu_name;
        gradeMap.put(course,new kaoshi(normal_score,test_score));
    }
    ChooseClass(String stu_name, String course, String test_score){
        this.num = stu_name;
        gradeMap.put(course,new Inspect_Score(test_score));
    }
    void Setgrade(String course, String normal_score, String test_score){
        if(!gradeMap.containsKey(course))
            gradeMap.put(course, new kaoshi(normal_score,test_score));
    }
    void Setgrade(String course, String test_score){
        if(!gradeMap.containsKey(course))
            gradeMap.put(course,new Inspect_Score(test_score));
    }

}
分析: 1. 定义了变量num用于存储学生姓名,并在类构造函数中初始化; 2. 定义了gradeMap用于存储学生的不同课程成绩,使用TreeMap实现对键值的排序和管理; 3. 设计了两个构造方法,分别用于添加考试成绩和其他成绩(如期末测试); 4. 设计了两个Setgrade()方法,用于修改已有的成绩记录;

不足之处:

  1. 变量命名不规范,例如变量gradeMap的命名,应当使用驼峰命名法,改为gradeMap;
  2. 不够精简,代码重复度较高,可以对相似的构造函数和Setgrade()方法进行重构,减少代码复杂度;
  3. 异常处理不足,没有对输入错误等异常进行处理,需要加入相应的异常处理代码来保证代码的健壮性和稳定性。

班级类:

点击查看代码
class Class {
    String num;
    TreeMap<String, Student> students = new TreeMap<>(); //班级里的学生 学号 学生
    Class(String num){
        this.num = num;
    }
}
分析: 1. 定义了变量num用于存储班级编号,并在类构造函数中初始化; 2. 定义了变量students用于存储班级中所有学生信息,使用TreeMap实现对学号的排序和管理; 3. 设计了构造方法,用于创建班级的对象;

不足之处:

  1. 缺乏完善的班级管理功能,例如添加、修改、删除学生等操作,需要其他类或方法配合实现;
  2. 变量命名不规范,例如变量students的命名,应当使用驼峰命名法,改为students;
  3. 类名与关键字重复,Class是Java中的关键字,不建议用于类名。
    课程类
点击查看代码
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;
    }
}
分析: 1. 定义了变量type用于存储课程类型,例如必修课、选修课等; 2. 定义了变量test_way用于存储课程考核方式,例如考试、论文、课程设计等; 3. 定义了变量name用于存储课程名称; 4. 设计了构造函数,用于创建课程的对象。

代码逻辑很清晰,实现了基础的课程信息的存储和管理。不足之处可能包括:

  1. 缺乏完善的课程管理功能,例如添加、修改、删除课程等操作,需要其他类或方法配合实现;
  2. 变量命名不规范,例如变量test_way的命名,应当使用驼峰命名法,改为testWay;
  3. 类名首字母应该大写,改为Course。
    数据类:
点击查看代码
class Data_all {
    TreeMap<String, Course> courses;
    TreeMap<String, Class> classes = new TreeMap<>();
    TreeMap<String, ChooseClass> stu__st_cour;
    HashMap<String, ArrayList<String>> course_up = new HashMap<>();
    Data_all() {
        stu__st_cour = new TreeMap<>(new Comparator<String>() {
            @Override
            public 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 e) {
                }
                return 0;
            }
        });//重写排序
        courses = new TreeMap<>(new Comparator<String>() {
            @Override
            public 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 e) {
                }
                return 0;
            }
        });
    }
    void setCourses(String name, String type, String test_way) {
        if (!courses.containsKey(name)) {
            courses.put(name, new Course(name, type, test_way));
        }
    }
    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)) {
            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 ChooseClass(num, course, normal_score, end_score));
        } else {
            stu__st_cour.get(num).Setgrade(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 ChooseClass(num, course, end_score));
        } else {
            stu__st_cour.get(num).Setgrade(course, end_score);
        }
    }
    void course_up_add(String num, String course) {
        if (!course_up.containsKey(num)) {
            ArrayList<String> tem = new ArrayList<>();
            tem.add(course);
            course_up.put(num, tem);
        } else {
            course_up.get(num).add(course);
        }
    }
}
分析: 1. 定义了变量courses用于存储所有课程的信息,使用TreeMap实现对课程名称的排序和管理; 2. 定义了变量classes用于存储所有班级的信息,使用TreeMap实现对班级编号的排序和管理; 3. 定义了变量stu__st_cour用于存储学生选课及成绩的信息,使用TreeMap实现对学号的排序和管理; 4. 定义了变量course_up用于存储课程信用HashMap实现学号和选课列表的映射; 5. 设计了构造函数,在构造函数中对stu__st_cour和courses进行了排序和初始化; 6. 设计了多个方法,包括添加课程、添加班级、添加学生、添加选课信息、添加升学所需的选修课等; 7. 在添加选课信息的方法中,提供了两个重载方法,用于添加有成绩和无成绩的选课信息。

代码实现了基础的数据管理功能,包括对课程、班级和选课信息的存储、排序和管理,以及升学模块所需信息的存储。不足之处:

  1. 代码逻辑较为复杂,容易造成理解困难和维护困难;
  2. 变量命名不规范,例如变量stu__st_cour和变量course_up的命名,应当使用驼峰命名法,改为stuStCour和courseUp;
  3. 代码中存在硬编码,例如课程类型和考核方式,应当改为常量或枚举类型。

为增强代码的可读性和易维护性,需要尽量减少硬编码和冗余代码,同时注意变量命名规范和代码结构清晰易懂等方面。也可以考虑使用面向对象设计思想,将代码拆分为多个类,以提高代码的可扩展性和可重用性。
分数类:

点击查看代码
abstract class Score {
    String total_scores = "-100";
}
分析: 1. 抽象类Score没有具体的实现逻辑,需要在子类中实现具体的业务逻辑; 2. 变量total_scores没有提供可以设置值的方法,也没有定义getTotalScores方法获取总分,无法使用或修改total_scores值; 3. 变量total_scores命名不规范,应当使用驼峰命名法,改为totalScores。

学生类:

点击查看代码
class Student {
    String name;
    String num;
    Student(String name, String num) {
        this.name = name;
        this.num = num;
    }
}
分析 1. 定义了变量name用于存储学生姓名; 2. 定义了变量num用于存储学生学号; 3. 设计了构造函数,用于创建学生的对象。

代码逻辑很清晰,实现了基础的学生信息的存储和管理。不足之处:

  1. 在代码中没有对变量进行封装,可以直接通过对象名访问到变量。

总体分析:
起初搞不懂选课类如何解耦合,搞不懂数据储存模式,造成了很多困难。但最终一一克服了。选用了一种较复杂的储存方式给后续的维护带来挺高困难。。

  1. 命名规范:类名、方法名、变量名采用驼峰命名法,明确易懂;
  2. OOP原则:面向对象的编程思想,封装、继承、多态得到良好的体现;
  3. 安全性:对于属性未进行任何权限控制,可以通过对象直接访问,影响安全性;
  4. 可维护性:采用简单直接的语言描述、遵循单一职责原则实现各部分代码,易于后期修改和维护;
  5. 可读性:代码注释清晰明了,可以快速理解代码含义,易于团队协作;
  6. 功能性:各部分代码功能齐全,结构清晰,易于扩展和优化;
  7. 性能:获取输入、输出等数据时,采用ArrayList存储,虽然效率较高,但数据量过大时,可能存在性能问题。

课程成绩统计-2

类设计及分析:
计算类:

点击查看代码
class Calculate_grades {
    final float normal_weight = 0.3f;
    final float end_weight = 0.7f;
    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()) {
            String key = entry.getKey();
            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(((Lab_Score) 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+")) {
                value.total_scores = String.valueOf((int)(normal_weight*Integer.parseInt(((Test_Score) value).normal_score)
                        + end_weight*Integer.parseInt(((Test_Score) value).end_score)));
            }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+")){
                int count = Integer.parseInt(((Lab_Score) value).lab_num);
                int sum = 0;
                for (Integer score : ((Lab_Score) value).scores) {
                    sum+=score;
                }
                value.total_scores = String.valueOf(sum/count);
            }
        });
    }
}
分析 代码设计较为复杂,实现了完整的数据存储功能和添加业务操作。其中的优点在于可以存储和管理选课信息,记录学生的成绩,存储实验分数等信息。不足之处包括:
  1. 代码复杂度较高,可能不易维护;
  2. 未对变量进行封装,可以直接通过对象名访问到变量;
  3. 代码中使用了一些不规范的变量命名,例如stu__st_cour变量名过长且含有下划线,建议修改为stu_st_cour等。
    班级类:
点击查看代码
class Class {
    String num;
    TreeMap<String, Student> students = new TreeMap<>(); //班级里的学生 学号 学生
    Class(String num){
        this.num = num;
    }
}
分析: 1. 定义了变量num用于存储班级编号; 2. 定义了变量students用于存储班级内所有学生的信息; 3. 设计了构造函数,用于创建班级的对象。

代码逻辑很清晰,实现了基础的班级信息的存储和管理。其优点在于使用了TreeMap存储学生信息,使得班级内的学生可以按照学号有序排列,方便后续管理。不足之处包括:

  1. 在代码中没有对变量进行封装,可以直接通过对象名访问到变量;
    课程类:
点击查看代码
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;
    }
}
分析: 1. 定义了变量type用于存储课程类型; 2. 定义了变量test_way用于存储考核方式; 3. 定义了变量name用于存储课程名称; 4. 设计了构造函数,用于创建课程的对象。

代码逻辑简单明了,实现了课程信息的存储,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 变量命名不规范,应当使用驼峰命名法命名变量。
    数据类:
点击查看代码
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:选课类
    WrongFormat_Check output = new WrongFormat_Check();
    Data_storage(){
        stu__st_cour = new TreeMap<>(new Comparator<String>(){//学生和选课类结合
            @Override
            public 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 e) {
                }
                return 0;
            }
        });//重写排序
        courses = new TreeMap<>(new Comparator<String>() {
            @Override
            public 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 e) {
                }
                return 0;
            }
        });
    }
    void setCourses(String name, String type, String test_way){
        if(!courses.containsKey(name)) {
            courses.put(name, new Course(name, type, test_way));
            courses.get(name);
        }
    }
    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)){
            classes.get(clas_num).students.put(num,new Student(name,num));
            classes.get(clas_num).students.get(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=4;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);
        }
    }
}
分析: 1. 定义了变量courses用于存储所有的课程; 2. 定义了变量classes用于存储所有的班级; 3. 定义了变量stu__st_cour用于存储学生选课信息; 4. 定义了变量output用于输出格式错误信息; 5. 设计了构造函数,用于创建Data_storage的对象; 6. 设计了一些方法,包括setCourses、setClasses、setStudents、setStu__st_courAndMap和set_lab_grades,用于添加课程、班级、学生或者更新学生选课信息等。

代码设计较为复杂,实现了完整的数据存储功能和添加业务操作。其中的优点在于可以存储和管理选课信息,记录学生的成绩,存储实验分数等信息。不足之处可能包括:

  1. 代码复杂度较高,可能不易维护;
  2. 未对变量进行封装,可以直接通过对象名访问到变量;
  3. 代码中使用了一些不规范的变量命名,例如stu__st_cour变量名过长且含有下划线,建议修改为stu_st_cour等。
    输入类:
点击查看代码
class Input_Format {
    String regex_c = "^[\\u4E00-\\u9FA5A-Za-z0-9]{1,10} +(必修|选修|实验)? *(考试|考察|实验)?$";
    String regex_CS = "^\\d{8}\\s+[\\u4E00-\\u9FA5A-Za-z]{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-Z ]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s[4-9]\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){1,20}$";
    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)){
            if(strings[1].equals("必修")&&strings[2].equals("考试")){
                data_storage.setCourses(strings[0],strings[1],strings[2]);
            }else if(strings[1].equals("选修")&&!strings[2].equals("实验")){
                data_storage.setCourses(strings[0],strings[1],strings[2]);
            }else if(strings[1].equals("实验")&&strings[2].equals("实验")){
                data_storage.setCourses(strings[0],strings[1],strings[2]);

            }
        }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(Integer.parseInt(strings[3])>=4&&Integer.parseInt(strings[3])<=9&&strings.length == 4+Integer.parseInt(strings[3])){
                        data_storage.set_lab_grades(strings[0],strings[2],strings[3],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(" ");
    }
}
分析: 1. 定义了正则表达式用于校验输入的格式; 2. 定义了变量isEnd表示输入是否结束; 3. 实现了输入数据的分割、存储和处理等功能。

该类主要是用于处理输入文件格式,根据输入的内容,存储到特定的数据结构中,以便后续统计分析。这个类的好处在于将输入数据的处理和存储封装在一起,并且使用正则表达式进行格式校验,可以快速判断输入的数据格式是否合法。但是该类还存在以下不足之处:

  1. 程序的注释不够详细,不便于他人理解代码的意图;
  2. 类、方法和变量的命名不够规范,不易读不易理解;
  3. 没有对类的函数和变量进行封装,不够安全、易维护。
    考察分数类:
点击查看代码
class Inspect_Score extends Score{
    String end_score = "-100";
    Inspect_Score(String end_score) {
        this.end_score = end_score;
    }
}
分析: 1. 定义了变量end_score用于存储考核分数; 2. 设计了构造函数,用于创建考核分数对象。

代码逻辑简单明了,实现了考核分数的存储,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 在构造函数中只接收了一个参数,无法得出总分,而实际应该将normal_score和end_score进行计算并得出总分;
  3. 变量命名不规范,应当使用驼峰命名法命名变量。
    输出类:
点击查看代码
class Output_Format {
    Calculate_grades calculate = new Calculate_grades();
    String regex_c = "^[\\u4E00-\\u9FA5A-Za-z0-9]{1,10} +(必修|选修|实验)? *(考试|考察|实验)?$";
    String regex_CS = "^\\d{8}\\s+[\\u4E00-\\u9FA5A-Za-z]{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-Z ]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s([4-9]|1[0-9]|20)\\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)){
                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");
            }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("实验")&&Integer.parseInt(tem[3])>=4&&Integer.parseInt(tem[3])<=9&&tem.length!=4+Integer.parseInt(tem[3]))
                            data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
                        if(data.courses.get(tem[2]).test_way.equals("实验")&&(Integer.parseInt(tem[3])<4||Integer.parseInt(tem[3])>9)) {
                            data.output.add_output("wrong format");
                        }
                    }
                }
            }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("选修")) {
                    if(value.test_way.equals("考察"))
                        data.output.add_output(key + " " + tem[1] + " " + tem[2]);
                    else
                        data.output.add_output(key + " " + tem[0] + " " + tem[1] + " " + tem[2]);
                } else if (value.type.equals("必修")) {
                    data.output.add_output(key + " " + tem[0] + " " + tem[1] + " " + tem[2]);
                } else if(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);
    }
}
分析: 代码的复杂度较高,应该拆分成几个类用于,拆分类的作用。部分变量和方法的命名不满足驼峰形式; 学生类:
点击查看代码
class Student {
    String name;
    String num;
    Student(String name, String num) {
        this.name = name;
        this.num = num;
    }
}
分析: 1. 定义了变量name用于存储学生姓名; 2. 定义了变量num用于存储学生学号; 3. 设计了构造函数,用于创建学生对象。

代码逻辑简单明了,实现了学生姓名和学号的存储,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 变量命名不规范,应当使用驼峰命名法命名变量。
    选课类:
点击查看代码
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));
    }

}
分析: 1. 定义了变量num,用于存储学生学号; 2. 定义了变量gradeMap,用于存储学生所有的成绩信息; 3. 设计了多个构造函数和方法,用于向学生信息中添加各种成绩信息。

代码相对比较复杂,主要实现了学生各种成绩的存储,但存在一些不足之处:

  1. 方法和变量命名不规范,应该使用驼峰命名法命名;
  2. 没有提供Getter和Setter方法,无法对类的成员变量进行访问和修改;
  3. 变量的数据类型可以考虑如何更加合适地存储;
    考试分数类:
点击查看代码
class Test_Score extends Score{
    String normal_score="-100";
    String end_score="-100";
    Test_Score(String normal_score,String end_score) {
        this.normal_score = normal_score;
        this.end_score = end_score;
    }
}
分析: 1. 定义了变量normal_score用于存储测试分数; 2. 定义了变量end_score用于存储考核分数; 3. 设计了构造函数,用于创建测试分数对象。

代码逻辑简单明了,实现了测试分数和考核分数的存储,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 在构造函数中只接收了两个参数,无法得出总分,而实际应该将normal_score和end_score进行计算并得出总分;
  3. 变量命名不规范,应当使用驼峰命名法命名变量。
    实验成绩类:
点击查看代码
class Lab_Score extends Score {
    String lab_num;//试验次数
    final int min_num = 4;
    final int max_num = 9;
    ArrayList<Integer> scores = new ArrayList<>();
    Lab_Score(String lab_num,ArrayList<Integer> scores){
        this.lab_num = lab_num;
        this.scores = scores;
    }
}
分析: 1. 定义了变量lab_num用于存储试验次数; 2. 定义了常量min_num表示实验最少需要进行的次数; 3. 定义了常量max_num表示实验最多可以进行的次数; 4. 定义了一个ArrayList类型的变量scores用于存储实验分数,可通过ArrayList动态添加分数; 5. 设计了构造函数,用于创建实验分数对象。

代码逻辑简单明了,实现了实验次数和实验分数的存储,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 变量命名不规范,应当使用驼峰命名法命名变量。
    检查错误类:
点击查看代码
class WrongFormat_Check {
    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);
    }
}
分析: 1. 定义了一个List类型的变量output用于存储输出结果; 2. 定义了一个List类型的变量input用于存储输入数据; 3. 定义了两个方法add_output和add_input用于添加输出和输入数据。

代码逻辑简单明了,实现了存储输入输出数据的功能,但存在一些不足之处:

  1. 未对成员变量进行封装,可以随意通过对象名访问变量;
  2. 类名不规范,应当符合类名的驼峰命名法命名规范;
  3. add_output和add_input方法未进行参数类型校验,应当对输入参数类型进行校验,避免类型转换错误。

总体分析:

  1. 命名规范:类名、方法名、变量名采用驼峰命名法,明确易懂;
  2. OOP原则:面向对象的编程思想,封装、继承、多态得到良好的体现;
  3. 安全性:对于属性未进行任何权限控制,可以通过对象直接访问,影响安全性;
  4. 可维护性:采用简单直接的语言描述、遵循单一职责原则实现各部分代码,易于后期修改和维护;
  5. 可读性:代码注释清晰明了,可以快速理解代码含义,易于团队协作;
  6. 功能性:各部分代码功能齐全,结构清晰,易于扩展和优化;
  7. 性能:获取输入、输出等数据时,采用ArrayList存储,虽然效率较高,但数据量过大时,可能存在性能问题。

标签:String,课程,程序,num,output,score,成绩,data,tem
From: https://www.cnblogs.com/22206116LC/p/17500044.html

相关文章

  • Java 程序控制结构
    Java程序控制结构1.顺序结构即按照从上到下依次执行到main()方法结束2.分支结构单分支(if)双分支(if-else)多分支(ifelseif...)嵌套分支(分支里面嵌套分支,建议不超过3层)Switch分支switch(表达式)case常量1:...;break;...............................
  • JAVA面向对象程序设计_PTA题目集07-11总结分析
    JAVA面向对象程序设计_PTA题目集07-11总结分析前言:天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为。所以动心忍性,增益其所不能。随堂检测在最末浅析。 题目集七:知识点:类间设计,类的设计。题量:一题,菜单计价五。难度:八个满分。 题目集八:知识点:类......
  • 绝对干货推荐-人工智能本科学位的完整4年课程规划
       对于想要入坑人工智能和机器学习领域的本科生而言,应该如何规划自己的四年大学生活,为你将来的职业做好准备呢?本文给出了一个四年制人工智能本科学位设计完整的课程规划,需要的朋友可以仔细看看。    这些课程旨在为人工智能和计算机科学领域的新手,提供广度和深度的知识......
  • 最新《动手学习深度学习》配套课程视频、笔记、ppt等资源整理分享
        《动手学习深度学习》是李沐老师(AWS资深首席科学家,美国卡内基梅隆大学计算机系博士)主讲的一系列深度学习视频。本项目收集了我们在寒假期间学习《动手学习深度学习》过程中详细的markdown笔记和相关的jupyter代码。赠人玫瑰,手留余香,我们将所有的markdown笔记开源,希望在自......
  • 人工智能本科学位的完整4年课程规划
       对于想要入坑人工智能和机器学习领域的本科生而言,应该如何规划自己的四年大学生活,为你将来的职业做好准备呢?本文给出了一个四年制人工智能本科学位设计完整的课程规划,需要的朋友可以仔细看看。    这些课程旨在为人工智能和计算机科学领域的新手,提供广度和深度的知识......
  • 李宏毅最新-深度学习/机器学习课程2021-课程视频及ppt
    课程描述    由国立台湾大学李宏毅老师主讲的纯中文版,2021年机器学习(深度学习)开课了,课程相关的部分资源已经release出来了,今年课程新增了很多新的前沿的内容,分享给大家。  课程大纲课程主页https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.html 课程视频截图 ......
  • MIT-医疗机器学习2019-课程推荐
    课程介绍    本课程向学生介绍医疗保健中的机器学习,包括临床数据的性质以及将机器学习用于风险分层,疾病进展建模,精密医学,诊断,亚型发现和改善临床工作流程的用途。主题包括因果关系,可解释性,算法公平性,时间序列分析,图形模型,深度学习和迁移学习。来自波士顿地区的临床医生的客座讲......
  • blendOS 2 已经问世,并支持开箱即用的Android应用程序
    导读当我第一次看到 blendOS 时,这个发行版承诺提供 Arch Linux、FedoraLinux和Ubuntu的混合体,但现在 blendOS2 已经发布了,并承诺更多,例如开箱即用的 Android 应用程序支持。blendOS2 内置的 Android 应用支持实现得益于 WayDroid 项目,这是一个基于容......
  • 第一阶段C++基础入门(黑马程序员)——Day2
    3运算符作用:用于执行代码的运算本章主要学习以下几类运算符:运算符类型作用算术运算符用于处理四则运算赋值运算符用于将表达式的值赋值给变量比较运算符用于表达式的比较,并返回一个真值或假值逻辑运算符用于根据表达式的值返回真值或假值3.1算术运算符作用:用于处理四则运算算术运......
  • 计算机科学|人工智能相关领域历史最全免费课程整理分享
        计算机科学是系统性研究信息与计算的理论基础以及它们在计算机系统中如何实现与应用的实用技术的学科。它通常被形容为对那些创造、描述以及转换信息的算法处理的系统研究。计算机科学包含很多分支领域;有些强调特定结果的计算,比如计算机图形学;而有些是探讨计算问题的性质,比......