PTA第三次总结作业

南昌航空大学 222019班 22201137 朱晓天

关于这段时间的OOP学习

这一段时间呢,我们学习的最主要的两块内容分别是JAVA中的容器和JAVAFX,这一段时间的题目集也大多都是考察JAVA中的一些容器的,像HashSet、HashMap、ArrayList这些。这一块的知识就基础的知识点而言还是比较简单的,没有什么难以理解的东西,但是在实际的应用中,这些容器的用法就比较灵活了,这种灵活就使得这些容器在实际应用中的难度加大了,而且有时候这些容器有很多我们不知道的方法,在面对有些要求的时候,我往往会因为不知道哪个容器可以实现要求而不知道选择哪个容器,在之后查找每个常用的容器中所有的方法,我总会发现一些新的东西,并且就能够帮助我解决问题。

PTA作业分析

7-1 统计Java程序中关键词的出现次数

编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:

  • Java中共有53个关键字(自行百度)
  • 从键盘输入一段源码,统计这段源码中出现的关键字的数量
  • 注释中出现的关键字不用统计
  • 字符串中出现的关键字不用统计
  • 统计出的关键字及数量按照关键字升序进行排序输出
  • 未输入源码则认为输入非法

输入格式:

输入Java源码字符串,可以一行或多行,以exit行作为结束标志

输出格式:

  • 当未输入源码时,程序输出Wrong Format
  • 当没有统计数据时,输出为空
  • 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner input = new Scanner(System.in);
        String inputLine = input.nextLine();
        if(inputLine.contains("/*") && !inputLine.matches("\".*/\\*\".*"))  {
                inputLine = input.next();
                while (input.hasNext() && !inputLine.contains("*/")){//不计算块注释
                    inputLine = input.next();
                }
                inputLine = input.next();
        }
        List<String> list = new ArrayList<>();
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        boolean flag=false;
        list.add(inputLine);
        while (!inputLine.equals("exit")){
            inputLine=input.nextLine();
            if(inputLine.contains("/*") && !inputLine.matches("\".*/\\*\".*"))  {
                inputLine = input.next();
                while (input.hasNext() && !inputLine.contains("*/")){//不计算块注释
                    inputLine = input.next();
                }
                inputLine = input.next();
            }
            list.add(inputLine);
            flag=true;
        }
        if(flag==false){
            System.out.println("Wrong Format");return;
        }
        String[] s2;
        for (int i = 0; i <= list.size() - 1; i++) {
            String str = list.get(i);
            str= str.replaceAll("//.*", " ").replaceAll("\".*\"", " ");//去掉单行注释和引号里面的内容
            str = str.replaceAll("\".*?\"", " ");
            str = str.replaceAll("=", "a");
            str = str.replaceAll(">", " ");
            str = str.replaceAll("<", " ");
            str = str.replace("+", " ");
            str = str.replaceAll("-", " ");
            str = str.replaceAll("\\p{P}", " ");
            s2 = str.split(" ");
            for (String we : s2) {
                if (s2.length != 0 && s2 != null) {
                    list1.add(we.trim().replaceAll("\\s", ""));
                }
            }
        }
        list1.toString().replaceAll(" ","");
        Set<String> keywordSet = getKeywordSet();
        for (int i = 0; i < list1.size(); i++) {
            if (keywordSet.contains(list1.get(i))) {
                list2.add(list1.get(i));
            }
        }
        Map<String, Integer> keywordCounts = new TreeMap<>();
        for (String keyword : list2) {
            keywordCounts.put(keyword, keywordCounts.getOrDefault(keyword, 0) + 1);
        }
        for (Map.Entry<String, Integer> entry : keywordCounts.entrySet()) {
            System.out.println(entry.getValue() + "\t" + entry.getKey());
        }
    }

    public static Set<String> getKeywordSet() {
        String[] keyWordString = {"abstract", "assert", "boolean", "break", "byte", "case", "catch",
                "char", "class", "const", "continue", "default", "do", "double", "else", "enum",
                "extends", "for", "final", "finally", "float", "goto", "if", "implements", "import",
                "instanceof", "int", "interface", "long", "native", "new", "package", "private",
                "protected", "public", "return", "short", "static", "strictfp", "super", "switch",
                "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile",
                "while", "true", "false", "null"};
        Set<String> keyword = new HashSet<>(Arrays.asList(keyWordString));
        return keyword;
    }
}

分析

这种统计关键词的题目是考察容器的题目中比较经典的题目了,在这个题目中,我们要去掉所有的注释中的内容,在这里有很多种处理方式,而我选择的处理方式是用contains方法匹配注释的符号,然后对输入的内容进行覆盖,将覆盖后的内容存入容器中,这样就可以将注释中的内容去掉了,多行注释也是一样的,只是要覆盖两次,匹配前面的起始符,进行一次覆盖,匹配到结束符再进行一次覆盖。之后我们匹配关键词,将匹配到的关键词存入TreeMap中,在之后的遍历输出中,我们要将TreeMap转换为set遍历,这里要用到entrySet()方法。

问题

在做这一题的时候,我遇到最大的问题就是我想要将文本记得符号去掉的时候,我也选用我去掉注释的方法的时候,输出会出现空的字符串,我一直找不出造成这种情况的原因,之后改成用replaceAll去掉所有符号这个问题就解决了。

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

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

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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

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

public class Main {
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        String str=input.nextLine();
        Process processer=new Process();
        while(!str.equals("end")){
            processer.process(str);
            str=input.nextLine();
        }
        processer.showStudents();
        processer.showCourses();
        processer.showClasses();
    }
}
/* 
 * 信息处理类
 */
class Process{
    ArrayList<Course> courseList=new ArrayList<>();
    ArrayList<Student> studentList=new ArrayList<>();
    ArrayList<Class> classList=new ArrayList<>();
    ArrayList<ChooseCourses> chooseList=new ArrayList<>();

    public void process(String str){
        Check check=new Check();
        int choice=check.checkInput(str);
        switch(choice){
            case 0:
                System.out.println("wrong format");
                break;
            case 1:
                courseMessage(str);
                break;
            case 2:
                markMessage(str);
                break;
        }
    }

    public boolean checkCourse(Course course){
        if(course.getType().equals("必修")&&course.getTextType().equals("考试")){
            return true;
        }
        if(course.getType().equals("选修")&&(course.getTextType().equals("考试")||course.getTextType().equals("考察"))){
            return true;
        }
        System.out.println(course.getCourseName()+" : course type & access mode mismatch");
        return false;
    }

    public Course searchCourse(String courseName){
        for(Course course:courseList){
            if(course.getCourseName().equals(courseName))
                return course;
        }
        return null;
    }

    public void courseMessage(String str){
        String[] message=str.split(" ");

        String courseName=message[0];
        String type=message[1];
        String textType=message[2];

        Course course=new Course(courseName,type,textType);

        if(checkCourse(course)){
            if(searchCourse(courseName)==null){
                courseList.add(course);
            }
        }
    }

    public Class searchClass(String classID){
        for(Class cls:classList){
            if(cls.getClassID().equals(classID))
                return cls;
        }
        return null;
    }

    public boolean searchStudent(String ID){
        for(Student stu:studentList){
            if(stu.getStuID().equals(ID))
                return true;
        }
        return false;
    }

    public boolean searchChooseCourse(String stuName,String courseName){
        for(ChooseCourses cs:chooseList){
            if(cs.student.getStuName().equals(stuName)&&cs.course.getCourseName().equals(courseName))
                return true;
        }
        return false;
    }

    public void markMessage(String str){
        String messages[]=str.split(" ");

        String stuID= messages[0];//学生学号
        String classID= messages[0].substring(0,6);
        String name=messages[1];//学生姓名
        String courseName=messages[2];//课程名字

        //如果该班级第一次出现
        if(searchClass(classID)==null){
            Class cla=new Class(classID);
            classList.add(cla);
        }

        Student stu=new Student(stuID,name,classID);
        if(!searchStudent(stuID))
            studentList.add(stu);//将学生加入列表中
        //课程不存在
        if(searchCourse(courseName)==null){
            System.out.println(courseName+" "+"does not exist");
        }
        //当课程存在时
        else if(searchCourse(courseName)!=null){
            Course course=searchCourse(courseName);
            //考察
            if(messages.length==4&&course.textType.equals("考察")){
                int finalScores= Integer.parseInt(messages[3]);
                AssessmentMark assessmentMark=new AssessmentMark(finalScores);
                ChooseCourses chooseCourse=new ChooseCourses(course,stu,assessmentMark);
                if(!searchChooseCourse(name,courseName))
                    chooseList.add(chooseCourse);
            }
            //考试
            else if(messages.length==5&&course.textType.equals("考试")){
                int dailyScores= Integer.parseInt(messages[3]);
                int finalScores= Integer.parseInt(messages[4]);
                TextMark textMark=new TextMark(dailyScores,finalScores);
                ChooseCourses chooseCourse=new ChooseCourses(course,stu,textMark);
                chooseList.add(chooseCourse);
            }
            else{
                System.out.println(stuID+" "+name+" "+": access mode mismatch");
            }
        }
    }
    public void showStudents(){
        Collections.sort(studentList);
        for(int i=0;i<studentList.size();i++){
            Student stu=studentList.get(i);
            //从总选课表listChooseCourse中获取该生的选课记录
            ArrayList<ChooseCourses> stuCourseSelects=getStudentSelects(stu.getStuID());
            if(stuCourseSelects.size()!=0) {
                System.out.println(stu.getStuID()+" "+stu.getStuName()+" "+getAvgTotalScore(stuCourseSelects));
            }
            else if(stuCourseSelects.size()==0){
                System.out.println(stu.getStuID()+" "+stu.getStuName()+" "+"did not take any exams");
            }
        }
    }

    public void showCourses(){
        Collections.sort(courseList);
        for(int i=0;i<courseList.size();i++){
            Course course=courseList.get(i);
            ArrayList<ChooseCourses> stuCourseSelects=getCourseSelects(course.getCourseName());
            if(stuCourseSelects.size()!=0){
                if(course.textType.equals("考试"))
                    System.out.println(course.getCourseName()+" "+getAvgDailyScore(stuCourseSelects)+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects));
                if(course.textType.equals("考察"))
                    System.out.println(course.getCourseName()+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects));
            }
            else if(stuCourseSelects.size()==0){
                System.out.println(course.courseName+" "+"has no grades yet");
            }
        }
    }

    public void showClasses(){
        Collections.sort(classList);
        for(int i=0;i<classList.size();i++){
            Class cls=classList.get(i);
            ArrayList<ChooseCourses> stuCourseSelects=getClassSelects(cls.getClassID());
            if(stuCourseSelects.size()!=0){
                System.out.println(cls.getClassID()+" "+getAvgTotalScore(stuCourseSelects));
            }
            else if(stuCourseSelects.size()==0){
                System.out.println(cls.getClassID()+" "+"has no grades yet");
            }
        }
    }

    public ArrayList<ChooseCourses> getStudentSelects(String ID){
        ArrayList<ChooseCourses> choose=new ArrayList<>();
        for(ChooseCourses cos:chooseList) {
            if (cos.student.getStuID().equals(ID))
                choose.add(cos);
        }
        return choose;
    }
    
    public ArrayList<ChooseCourses> getCourseSelects(String courseName){
        ArrayList<ChooseCourses> choose=new ArrayList<>();
        for(ChooseCourses cos:chooseList) {
            if (cos.course.getCourseName().equals(courseName))
                choose.add(cos);
        }
        return choose;
    }

    public ArrayList<ChooseCourses> getClassSelects(String classID){
        ArrayList<ChooseCourses> choose =new ArrayList<>();
        for(ChooseCourses cos:chooseList) {
            if (cos.student.getClassID().equals(classID))
                choose.add(cos);
        }
        return choose;
    }

    public int getAvgTotalScore(ArrayList<ChooseCourses> cs){
        int average=0;
        int sum=0;
        for(ChooseCourses c:cs){
            sum+=c.mark.getTotalScores();
        }
        average=sum/cs.size();
        return average;
    }

    public int getAvgDailyScore(ArrayList<ChooseCourses> cs){
        int average=0;
        int sum=0;
        for(ChooseCourses c:cs){
            if(c.course.getTextType().equals("考试")){
                sum+=c.mark.getDailyScores();
            }
        }
        average=sum/cs.size();
        return average;
    }

    public int getAvgFinalScore(ArrayList<ChooseCourses> cs){
        int average=0;
        int sum=0;
        for(ChooseCourses c:cs){
            sum+=c.mark.finalScores;
        }
        average=sum/cs.size();
        return average;
    }
}

class ChooseCourses{
    Course course;
    Student student;
    Mark mark;

    public ChooseCourses(Course course,Student student,Mark mark){
        this.course=course;
        this.student=student;
        this.mark=mark;
    }
}

class Course implements Comparable<Course>{
    protected String courseName;
    protected String type;//课程性质
    protected String textType;//考试形式

    public Course(){}

    public Course(String courseName,String type,String textType){
        this.courseName=courseName;
        this.type=type;
        this.textType=textType;
    }

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getTextType() {
        return textType;
    }

    public void setTextType(String textType) {
        this.textType = textType;
    }

    public int compareTo(Course o){
        Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
        return compare.compare(getCourseName(),o.getCourseName());
    }
}

class Student implements Comparable<Student>{
    protected String stuID;
    protected String stuName;
    protected String classID;
    
    public Student(){}

    public Student(String stuID,String stuName,String classID){
        this.stuID=stuID;
        this.stuName=stuName;
        this.classID=classID;
    }

    public String getStuID() {
        return stuID;
    }

    public void setStuID(String stuID) {
        this.stuID = stuID;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public String getClassID() {
        return classID;
    }

    public void setClassID(String classID) {
        this.classID = classID;
    }
    
    public int compareTo(Student o){
        int stuID1=Integer.parseInt(getStuID());
        int stuID2=Integer.parseInt(o.getStuID());
        if(stuID1>stuID2){
            return 1;
        }
        if(stuID1<stuID2){
            return -1;
        }
        else{
            return 0;
        }
    }
}

class Class implements Comparable<Class>{
    protected String classID;

    public Class(){}

    public Class(String classID){
        this.classID=classID;
    }

    public String getClassID(){
        return this.classID;
    }

    public void setClassID(String classID){
        this.classID=classID;
    }

    public int compareTo(Class o ){
        int class1=Integer.parseInt(getClassID());
        int class2=Integer.parseInt(o.getClassID());
        if(class1>class2){
            return 1;
        }
        else if(class1<class2){
            return -1;
        }
        else{
            return 0;
        }
    }
}

abstract class Mark{
    protected int finalScores;//期末成绩
    public Mark(){}

    public abstract int getDailyScores();
    public abstract int getTotalScores();
}
/*  
 * 考核成绩
*/
class TextMark extends Mark{
    protected int dailyScores;

    public TextMark(){}

    public TextMark(int dailyScores,int finalScores){
        this.dailyScores=dailyScores;
        this.finalScores=finalScores;
    }

    public int getDailyScores() {
        return dailyScores;
    }

    public void setDailyScores(int dailyScores) {
        this.dailyScores = dailyScores;
    }

    public int getFinalScores(){
        return 0;
    }

    public int getTotalScores(){
        return (int)(dailyScores*0.3+finalScores*0.7);
    }
}
/* 
 * 考察成绩
 */
class AssessmentMark extends Mark{
    public AssessmentMark(){}

    public AssessmentMark(int finalScores){
        this.finalScores=finalScores;
    }

    public int getFinalScores(){
        return finalScores;
    }

    public int getDailyScores(){
        return 0;
    }

    public int getTotalScores(){
        return finalScores;
    }
}
/* 
 * 检查输入信息模式
 */
class Check{
    static String stuNumCheck = "[0-9]{8}";
    static String stuNameCheck = "\\S{1,10}";
    static String scoreCheck = "([1-9]?[0-9]|100)";
    static String courseNameCheck = "\\S{1,10}";
    static String courseTypeCheck = "(选修|必修)";
    static String textTypeCheck = "(考试|考察)";
    //courseInput用于定义课程信息模式
    static String courseInput = courseNameCheck + " " + courseTypeCheck + " " + textTypeCheck;
    //scoreInput用于定义成绩信息模式
    static String scoreInput1 = stuNumCheck + " " + stuNameCheck + " " + courseNameCheck + " " + scoreCheck ;//考察方式
    static String scoreInput2=  stuNumCheck + " " + stuNameCheck + " " + courseNameCheck + " " +scoreCheck + " " +scoreCheck;//考试方式
    public Check() {}

    public  int checkInput(String s) {
        if (checkCourse(s))
            return 1;
        if (checkScores(s))
            return 2;
        return 0;
    }
    //课程信息
    private static boolean checkCourse(String s) {
        return s.matches(courseInput);
    }
    //成绩信息
    private static boolean checkScores(String s) {
        if(s.matches(scoreInput1)||s.matches(scoreInput2))
            return true;
        return false;
    }
}

 

 分析

课程成绩统计程序是目前我们写过的PTA作业中最难的一次作业了,这一次的程序设计中要求很多,我们需要完成的内容也就很多,首先我们需要解决的问题就是匹配输入正确,在这里匹配输入正确我选择使用正则表达式,之后就是需要对考虑输入的信息的处理,我就加了一个信息处理类,在信息处理类里面,会处理各类信息,并且把所有信息进行分类,存入不同的列表之中,再通过列表进行数据的处理。而不同课程的不同考核方式,其成绩分为不同的类,这些类都继承自成绩类,因为成绩需要排序,所以需要实现Comparable接口,在不同的类里面直接计算出考核的成绩,在列表里面直接用sort()就可以升序排列了。同样的,学生信息中的学号也要排序,所以学生类也要实现Comparable接口。三种不同的数据输出我选择在信息处理类里面写三个方法列表遍历输出,在主类里面依次调用三个方法即可。

问题

这次的PTA难度可以说是比较大的,我在进行程序设计的时候,信息匹配倒是很快就想出来用正则,但是在关于如何进行信息处理的时候我想了很久,一开始最主要的问题是卡在怎么把不同类型的信息分开处理,后来经过同学的提醒才想起来可以利用之前的正则表达式,匹配到的这一行信息是什么就进行什么的处理方式。

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

课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,

要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。

题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。

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

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。

考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重

考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重

实验次数至少4次,不超过9次

课程性质输入项:必修、选修、实验

考核方式输入选项:考试、考察、实验

考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

考试/考查课程成绩信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

2)学号由8位数字组成

3)姓名不超过10个字符

4)课程名称不超过10个字符

5)不特别输入班级信息,班级号是学号的前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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"

7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):

fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png

分析

这个题目比起上面的题目多了一些要求,加入了新的考核类型——实验,并且加上了成绩的权重,还要求我们成绩类不能使用继承了,要改成组合关系,要分成课程成绩类和分项成绩类,一开始的加入实验还比较简单,只需要改一下正则,在处理类里加个实验的处理就行了,但是之后的权重,需要我们把实验的次数放在课程信息里面输入,类还要重构,这个就有点难到我了,我也想了很多种改法,但是总有以个环节我没法实现。

关于最近课程的看法和建议

最近的JAVA课可以说有点很多,老师让我们自己准备JAVAFX,自己讲,在我自己准备的时候,我可以感觉到我学到的知识更加深刻了,但是同样也有缺点,就是学习效率太低了,我为了准备一节的内容花费了大概两三天的时间。而且老师平时上课的时候基本就是讲一些基础的知识,然后写一些示例,展示一些程序设计的方法,然后就让我们自己实操,进行练习,有的时候的课我都是听的一知半解的就开始自己做了,我希望老师能够提出一些能让我们思考的问题,给我们多一些思考的时间,让我们对知识点的理解更加深刻。

posted @ 2023-06-27 20:41  通召我的左拳  阅读(44)  评论(0)    收藏  举报