blog-3作业

发布时间 2023-06-28 15:41:03作者: 摩根!我的超人!

一、前言

本篇博客包含了以下Java的主要知识点:

  • 面向对象基础: 包括类和对象的基本概念、构造方法、访问权限和成员变量。
  • 面向对象设计原则: 重点讨论了继承和组合这两个重要的设计原则。要求学生深入理解它们的区别,并能根据实际需求选择恰当的设计原则。
  • 异常处理: 涉及到许多异常情况,要求学生能够正确处理这些异常情况。
  • 字符串处理: 涉及输入和输出的字符串处理,包括字符串的拆分、组合和转换等操作。
  • 基本控制流和数据结构: 例如循环、条件语句、数组和列表。

本次题目主要为PTA6-8次题目集,主要为课程成绩管理系统1,2和3,以及部分Java进阶知识的应用,难度偏高,数量适中,涵盖了多个细节和要求,包括异常处理和特殊情况的处理。

总的来说,这几道题目,能够全面测试学生的Java编程能力,包括面向对象设计原则、异常处理、字符串处理和基本的控制流和数据结构。完成这些题目后,我对Java编程有了更深入的理解。

二、题目

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)成绩平均分只取整数部分,小数部分丢弃

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


public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String s_record = s.nextLine();
        ParseInput handle=new ParseInput();
        while (!s_record.equals("end")) {
            handle.parseInput(s_record);
            s_record = s.nextLine();
        }

        handle.MySort();
        handle.studentScore();
        handle.CourseScore();
        handle.ClassScore();
    }
}

class ParseInput{
    private final ArrayList<SelectCourse> selectCourses = new ArrayList<>();
    private final ArrayList<Course> courses = new ArrayList<>();
    private final ArrayList<Student> students = new ArrayList<>();
    private final ArrayList<String> Class = new ArrayList<>();
    public void parseInput(String input){
        String []inputs=input.split(" ");

        if(InputMatching.matchingInput(input)==1){
            if(checkCourse(inputs[0])!=null)return;
            else {
                if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else courses.add(new Course(inputs[0],inputs[1],inputs[2]));
            }
        }
        else if(InputMatching.matchingInput(input)==2){

            Student newStudent = new Student(inputs[0],inputs[1]);
            if(!checkStudent(newStudent.getNum()))students.add(newStudent);
            if(!checkClass(inputs[0].substring(0,6))){
                Class.add(inputs[0].substring(0,6));
            }
            if(checkSelect(inputs[0],inputs[2]))return;
            Course findcourse=checkCourse(inputs[2]);
            if(findcourse==null){

                System.out.println(inputs[2]+" does not exist");
                return;
            }
            else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else{
                SelectCourse newSelectCourse=new SelectCourse();
                newSelectCourse.setCourse(findcourse);
                Grade grade;
                if(findcourse.getMethod().equals("考试")){
                    ExamGrade examGrade=new ExamGrade();
                    examGrade.setUsualGrade(Integer.parseInt(inputs[3]));
                    examGrade.setFinalGrade(Integer.parseInt(inputs[4]));
                    grade=examGrade;
                }
                else {
                    NoExamGrade noExamGrade=new NoExamGrade();
                    noExamGrade.setFinalGrade(Integer.parseInt(inputs[3]));
                    grade=noExamGrade;
                }
                newSelectCourse.setGrade(grade);
                newSelectCourse.setStudent(newStudent);
                selectCourses.add(newSelectCourse);
            }
        }
        else System.out.println("wrong format");
    }
    private Course checkCourse(String courseName){
        for (Course course:courses){
            if(course.getName().equals(courseName))return course;
        }
        return null;
    }
    private Boolean checkStudent(String num){
        for (Student student:students){
            if(student.getNum().equals(num))return true;
        }
        return false;
    }
    private Boolean checkClass(String classnum){
        for (String cname:Class){
            if(cname.equals(classnum))return true;
        }
        return false;
    }

    private Boolean checkSelect(String stunum,String cname){
        for (SelectCourse selectCourse:selectCourses){
            if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true;
        }
        return false;
    }

    public void studentScore(){

        for (Student student:students){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if (selectCourse.getStudent().getNum().equals(student.getNum()))
                {
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams");
            else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count));
        }
    }
    public void CourseScore(){
        for (Course course:courses){
            double sumUsualScore=0;
            double sumFinalScore=0;
            double sumTotalScore=0;
            int count=0;
            for(SelectCourse selectCourse:selectCourses){
                if(selectCourse.getCourse().getName().equals(course.getName())){
                    count++;
                    sumTotalScore+=selectCourse.getGrade().getTotalGrade();
                    sumFinalScore+=selectCourse.getGrade().getFinalGrade();
                    if(selectCourse.getCourse().getMethod().equals("考试")){
                        sumUsualScore+=selectCourse.getGrade().getUsualGrade();
                    }
                }
            }
            if (count==0) System.out.println(course.getName()+' '+"has no grades yet");
            else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
            else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
        }
    }
    public void ClassScore(){
        for (String classnum:Class){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(classnum+' '+"has no grades yet");
            else System.out.println(classnum+' '+(int)(sum/count));
        }
    }
    public void MySort(){
        students.sort(Comparator.comparing(Student::getNum));
        courses.sort((x,y)->{
            Collator instance = Collator.getInstance(Locale.CHINA);
            return instance.compare(x.getName(), y.getName());
        } );
        Collections.sort(Class);
    }
}


abstract class Grade{
    double TotalGrade;

    public int getTotalGrade() {
        return (int) TotalGrade;
    }

    public int getUsualGrade() {
        return 0;
    }

    public int getFinalGrade() {
        return 0;
    }

}

class ExamGrade extends Grade{
    int UsualGrade;
    int FinalGrade;
    public int getTotalGrade(){
        return (int)(0.3*this.getUsualGrade()+0.7*this.getFinalGrade());
    }

    public int getUsualGrade() {
        return UsualGrade;
    }

    public void setUsualGrade(int usualGrade) {
        UsualGrade = usualGrade;
    }

    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class NoExamGrade extends Grade{
    int FinalGrade;
    public int getTotalGrade(){
        return FinalGrade;
    }

    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class Course{
    String name;
    String kind;
    String method;

    public Course(String name, String kind, String method) {
        this.name = name;
        this.kind = kind;
        this.method = method;
    }

    public String getName() {
        return name;
    }

    public String getMethod() {
        return method;
    }

}

class Student{
    String num;
    String name;

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

    public String getNum() {
        return num;
    }

    public String getName() {
        return name;
    }

}

class SelectCourse{
    Course course;
    Student student;
    Grade grade;

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}


class InputMatching {
    static String stuNumMatching = "[0-9]{8}";
    static String stuNameMatching = "\\S{1,10}";
    static String scoreMatching = "(\\d|[1-9]\\d|100)";
    static String courseNameMatching = "\\S{1,10}";
    static String courseTypeMatching = "(选修|必修)";
    static String checkcourseTypeMatching = "(考试|考察)";
    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
            scoreMatching + "(\\s"+scoreMatching+")?";
    public static int matchingInput(String s) {
        if (matchingCourse(s)) {
            return 1;
        }
        if (matchingScore(s)) {
            return 2;
        }
        return 0;
    }

    private static boolean matchingCourse(String s) {
        return s.matches(courseInput);
    }

    private static boolean matchingScore(String s) {

        return s.matches(scoreInput);
    }
}

类图:

7-1 容器-HashMap-检索

输入多个学生的成绩信息,包括:学号、姓名、成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

使用HashMap存储学生信息,并实现根据学号的检索功能

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩

以“end”为输入结束标志

end之后输入某个学号,执行程序输出该生的详细信息

输出格式:

输出查询到的学生信息格式:学号+英文空格+姓名+英文空格+成绩

如果没有查询到,则输出:"The student "+查询的学号+" does not exist"

import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        HashMap<String, String[]> students = new HashMap<>();
        while (true) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] studentInfo = input.split(" ");
            String id = studentInfo[0];
            String name = studentInfo[1];
            String score = studentInfo[2];
            students.put(id, new String[]{name, score});
        }
        String searchId = scanner.nextLine();
        if (students.containsKey(searchId)) {
            System.out.println(searchId + " " + students.get(searchId)[0] + " " + students.get(searchId)[1]);
        } else {
            System.out.println("The student " + searchId + " does not exist");
        }
    }
}

7-2 容器-HashMap-排序

输入多个学生的成绩信息,包括:学号、姓名、成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

要求:使用HashMap存储学生信息。

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩

以“end”为输入结束标志

输出格式:

按学号从大到小的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+成绩

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Map<String, String[]> students = new HashMap<>();
        while (true) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] studentInfo = input.split(" ");
            String id = studentInfo[0];
            String name = studentInfo[1];
            String score = studentInfo[2];
            students.put(id, new String[]{name, score});
        }
        List<String> keys = new ArrayList<>(students.keySet());
        Collections.sort(keys, Collections.reverseOrder());
        for (String key : keys) {
            String[] studentInfo = students.get(key);
            System.out.println(key + " " + studentInfo[0] + " " + studentInfo[1]);
        }
    }
}

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

 

课程成绩统计程序-2在第一次的基础上增加了实验课,实验的总成绩等于课程每次实验成绩的平均分,实验课的成绩必须为实验。

实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩实验次数至少4次,不超过9次

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

实验课成绩格式:课程名称+英文空格+总成绩平均分

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


public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String s_record = s.nextLine();
        ParseInput handle=new ParseInput();
        while (!s_record.equals("end")) {
            handle.parseInput(s_record);
            s_record = s.nextLine();
        }

        handle.MySort();
        handle.studentScore();
        handle.CourseScore();
        handle.ClassScore();
    }
}

class ParseInput{
    private final ArrayList<SelectCourse> selectCourses = new ArrayList<>();
    private final ArrayList<Course> courses = new ArrayList<>();
    private final ArrayList<Student> students = new ArrayList<>();
    private final ArrayList<String> Class = new ArrayList<>();
    private final HashMap<String,String> courseMethod=new HashMap();
    public void parseInput(String input){
        String []inputs=input.split(" ");
        if(InputMatching.matchingInput(input)==1){
            courseMethod.put(inputs[0],inputs[2]);
            if(checkCourse(inputs[0])!=null)return;
            else {
                if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else if(inputs[1].equals("选修")&&!(inputs[2].equals("考试")||inputs[2].equals("考察"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else if(inputs[1].equals("实验")&&!(inputs[2].equals("实验"))){
                    System.out.println(inputs[0]+" : course type & access mode mismatch");
                }
                else courses.add(new Course(inputs[0],inputs[1],inputs[2]));
            }
        }
        else if(InputMatching.matchingInput(input)==2){
            Course findcourse=checkCourse(inputs[2]);
            if(inputs.length>5&&(Integer.parseInt(inputs[3])<4||Integer.parseInt(inputs[3])>9)) {
                System.out.println("wrong format");
                return;
            }
            Student newStudent = new Student(inputs[0],inputs[1]);
            if(!checkStudent(newStudent.getNum()))students.add(newStudent);
            if(!checkClass(inputs[0].substring(0,6))){
                Class.add(inputs[0].substring(0,6));
            }
            if(checkSelect(inputs[0],inputs[2]))return;
            if(findcourse==null){

                System.out.println(inputs[2]+" does not exist");
                return;
            }
            else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else if(findcourse.getMethod().equals("实验")&&(inputs.length-4!=Integer.parseInt(inputs[3]))){
                System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
            }
            else{
                SelectCourse newSelectCourse=new SelectCourse();
                newSelectCourse.setCourse(findcourse);
                Grade grade=null;
                if(findcourse.getMethod().equals("考试")){
                    ExamGrade examGrade=new ExamGrade();
                    examGrade.setUsualGrade(Integer.parseInt(inputs[3]));
                    examGrade.setFinalGrade(Integer.parseInt(inputs[4]));
                    grade=examGrade;
                }
                else if(findcourse.getMethod().equals("实验")){
                    NoExamGrade noExamGrade=new NoExamGrade();
                    double sumScore=0;
                    for (int i=4;i<inputs.length;i++)sumScore+=Integer.parseInt(inputs[i]);
                    noExamGrade.setFinalGrade((int)(sumScore/Integer.parseInt(inputs[3])));
                    grade=noExamGrade;
                }
                else {
                    NoExamGrade noExamGrade=new NoExamGrade();
                    noExamGrade.setFinalGrade(Integer.parseInt(inputs[3]));
                    grade=noExamGrade;
                }
                newSelectCourse.setGrade(grade);
                newSelectCourse.setStudent(newStudent);
                selectCourses.add(newSelectCourse);
            }
        }
        else System.out.println("wrong format");
    }
    private Course checkCourse(String courseName){
        for (Course course:courses){
            if(course.getName().equals(courseName))return course;
        }
        return null;
    }
    private Boolean checkStudent(String num){
        for (Student student:students){
            if(student.getNum().equals(num))return true;
        }
        return false;
    }
    private Boolean checkClass(String classnum){
        for (String cname:Class){
            if(cname.equals(classnum))return true;
        }
        return false;
    }

    private Boolean checkSelect(String stunum,String cname){
        for (SelectCourse selectCourse:selectCourses){
            if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true;
        }
        return false;
    }

    public void studentScore(){

        for (Student student:students){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if (selectCourse.getStudent().getNum().equals(student.getNum()))
                {
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams");
            else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count));
        }
    }
    public void CourseScore(){
        for (Course course:courses){
            double sumUsualScore=0;
            double sumFinalScore=0;
            double sumTotalScore=0;
            int count=0;
            for(SelectCourse selectCourse:selectCourses){
                if(selectCourse.getCourse().getName().equals(course.getName())){
                    count++;
                    sumTotalScore+=selectCourse.getGrade().getTotalGrade();
                    sumFinalScore+=selectCourse.getGrade().getFinalGrade();
                    if(selectCourse.getCourse().getMethod().equals("考试")){
                        sumUsualScore+=selectCourse.getGrade().getUsualGrade();
                    }
                }
            }
            if (count==0) System.out.println(course.getName()+' '+"has no grades yet");
            else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
            else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
            else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count));
        }
    }
    public void ClassScore(){
        for (String classnum:Class){
            double sum=0;
            int count=0;
            for (SelectCourse selectCourse:selectCourses){
                if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){
                    sum+=selectCourse.getGrade().getTotalGrade();
                    count++;
                }
            }
            if(count==0) System.out.println(classnum+' '+"has no grades yet");
            else System.out.println(classnum+' '+(int)(sum/count));
        }
    }
    public void MySort(){
        students.sort(Comparator.comparing(Student::getNum));
        courses.sort((x,y)->{
            Collator instance = Collator.getInstance(Locale.CHINA);
            return instance.compare(x.getName(), y.getName());
        } );
        Collections.sort(Class);
    }
}


abstract class Grade{
    double TotalGrade;

    public int getTotalGrade() {
        return (int) TotalGrade;
    }

    public int getUsualGrade() {
        return 0;
    }

    public int getFinalGrade() {
        return 0;
    }

}

class ExamGrade extends Grade{
    int UsualGrade;
    int FinalGrade;
    public int getTotalGrade(){
        return (int)(0.3*this.getUsualGrade()+0.7*this.getFinalGrade());
    }

    public int getUsualGrade() {
        return UsualGrade;
    }

    public void setUsualGrade(int usualGrade) {
        UsualGrade = usualGrade;
    }

    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class NoExamGrade extends Grade{
    int FinalGrade;
    public int getTotalGrade(){
        return FinalGrade;
    }

    public int getFinalGrade() {
        return FinalGrade;
    }

    public void setFinalGrade(int finalGrade) {
        FinalGrade = finalGrade;
    }
}
class Course{
    String name;
    String kind;
    String method;

    public Course(String name, String kind, String method) {
        this.name = name;
        this.kind = kind;
        this.method = method;
    }

    public String getName() {
        return name;
    }

    public String getMethod() {
        return method;
    }

}

class Student{
    String num;
    String name;

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

    public String getNum() {
        return num;
    }

    public String getName() {
        return name;
    }

}

class SelectCourse{
    Course course;
    Student student;
    Grade grade;

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}


class InputMatching {
    static String stuNumMatching = "[0-9]{8}";
    static String stuNameMatching = "\\S{1,10}";
    static String scoreMatching = "(\\d|[1-9]\\d|100)";
    static String courseNameMatching = "\\S{1,10}";
    static String courseTypeMatching = "(选修|必修|实验)";
    static String checkcourseTypeMatching = "(考试|考察|实验)";
    static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
    static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
            scoreMatching + "(\\s"+scoreMatching+")*";
    public static int matchingInput(String s) {
        if (matchingCourse(s)) {
            return 1;
        }
        if (matchingScore(s)) {
            return 2;
        }
        return 0;
    }

    private static boolean matchingCourse(String s) {
        return s.matches(courseInput);
    }

    private static boolean matchingScore(String s) {

        return s.matches(scoreInput);
    }

}

 

7-4 动物发声模拟器(多态)

设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩

其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。

//动物发生模拟器.  请在下面的【】处添加代码。
public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Dog dog = new Dog();
        Goat goat = new Goat();
        speak(cat);
        speak(dog);
        speak(goat);
    }
    // 定义静态方法speak()
 
    private static void speak(Animal animal) {
        System.out.println(animal.getAnimalClass() + "的叫声:" + animal.shout());
 
    }
 
}
 
//定义抽象类Animal
abstract class Animal {
    abstract public String getAnimalClass();
 
    abstract public String shout();
}
 
//基于Animal类,定义猫类Cat,并重写两个抽象方法
class Cat extends Animal {
 
    @Override
    public String getAnimalClass() {
        return "猫";
    }
 
    @Override
    public String shout() {
        return "喵喵";
 
    }
}
 
//基于Animal类,定义狗类Dog,并重写两个抽象方法
class Dog extends Animal {
 
    @Override
    public String getAnimalClass() {
        return "狗";
    }
 
    @Override
    public String shout() {
        return "汪汪";
 
    }
}
 
//基于Animal类,定义山羊类Goat,并重写两个抽象方法
class Goat extends Animal {
 
    @Override
    public String getAnimalClass() {
        return "山羊";
    }
 
    @Override
    public String shout() {
        return "咩咩";
 
    }
}

7-1 容器-ArrayList-排序

题目描述

编辑

输入多个学生的成绩信息,包括:学号、姓名、数学成绩、物理成绩。

学号是每个学生的唯一识别号,互不相同。

姓名可能会存在重复。

要求:使用ArrayList存储学生信息。

输入格式:

输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+数学成绩+英文空格+物理成绩

以“end”为输入结束标志

输出格式:

按数学/物理成绩之和从高到低的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+数学/物理成绩之和

成绩相同的情况,按输入的先后顺序输出。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<Student> students = new ArrayList<>();
        while (scanner.hasNext()) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] info = input.split("\\s+");
            String id = info[0];
            String name = info[1];
            int mathScore = Integer.parseInt(info[2]);
            int physicsScore = Integer.parseInt(info[3]);
            Student student = new Student(id, name, mathScore, physicsScore);
            students.add(student);
        }
        students.sort(new ScoreSumComparator().reversed().thenComparing(Student::getInputOrder));
        for (Student student : students) {
            System.out.println(student);
        }
    }

    private static class Student {
        private String id;
        private String name;
        private int mathScore;
        private int physicsScore;
        private int scoreSum;
        private static int inputOrder = 0;

        public Student(String id, String name, int mathScore, int physicsScore) {
            this.id = id;
            this.name = name;
            this.mathScore = mathScore;
            this.physicsScore = physicsScore;
            this.scoreSum = mathScore + physicsScore;
            inputOrder++;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public int getMathScore() {
            return mathScore;
        }

        public int getPhysicsScore() {
            return physicsScore;
        }

        public int getScoreSum() {
            return scoreSum;
        }

        public int getInputOrder() {
            return inputOrder;
        }

        @Override
        public String toString() {
            return id + " " + name + " " + scoreSum;
        }
    }

    private static class ScoreSumComparator implements Comparator<Student> {
        @Override
        public int compare(Student s1, Student s2) {
            if (s1.getScoreSum() != s2.getScoreSum()) {
                return s1.getScoreSum() - s2.getScoreSum();
            } else {
                return 0;
            }
        }
    }
}

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)成绩平均分只取整数部分,小数部分丢弃

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);
    }
}

 7-3 jmu-Java-02基本语法-03-身份证排序

  1. 输入n,然后连续输入n个身份证号。
  2. 然后根据输入的是sort1还是sort2,执行不同的功能。输入的不是sort1或sort2,则输出exit并退出。
    输入sort1,将每个身份证的年月日抽取出来,按年-月-日格式组装,然后对组装后的年-月-日升序输出。
    输入sort2,将所有身份证按照里面的年月日升序输出。

注意:处理输入的时候,全部使用ScannernextLine()方法,以免出错。

import java.text.SimpleDateFormat;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        List<String> idList = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            String id = scanner.nextLine();
            idList.add(id);
        }
        String sort = "";
        while (!sort.equals("exit")) {
            sort = scanner.nextLine();
            switch (sort) {
                case "sort1":
                    List<String> dateList = new ArrayList<>();
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    for (String id : idList) {
                        String dateStr = id.substring(6, 14);
                        try {
                            Date date = new SimpleDateFormat("yyyyMMdd").parse(dateStr);
                            String formattedDate = dateFormat.format(date);
                            dateList.add(formattedDate);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    Collections.sort(dateList);
                    for (String date : dateList) {
                        System.out.println(date);
                    }
                    break;
                case "sort2":
                    Collections.sort(idList, new Comparator<String>() {
                        @Override
                        public int compare(String o1, String o2) {
                            String dateStr1 = o1.substring(6, 14);
                            String dateStr2 = o2.substring(6, 14);
                            try {
                                Date date1 = new SimpleDateFormat("yyyyMMdd").parse(dateStr1);
                                Date date2 = new SimpleDateFormat("yyyyMMdd").parse(dateStr2);
                                return date1.compareTo(date2);
                            } catch (Exception e) {
                                e.printStackTrace();
                                return 0;
                            }
                        }
                    });
                    for (String id : idList) {
                        System.out.println(id);
                    }
                    break;
                case "exit":
                    System.out.println("exit");
                    break;
                default:
                    System.out.println("exit");
                    sort = "exit";
                    break;
            }
        }
    }
}

7-4 jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack

定义IntegerStack接口,用于声明一个存放Integer元素的栈的常见方法:

 
public Integer push(Integer item);
//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。

public Integer pop();   //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
public Integer peek();  //获得栈顶元素,如果为空,则返回null.
public boolean empty(); //如果为空返回true
public int size();      //返回栈中元素个数
 

定义IntegerStack的实现类ArrayIntegerStack,内部使用数组实现。创建时,可指定内部数组大小。

main方法说明

  1. 输入n,建立可包含n个元素的ArrayIntegerStack对象
  2. 输入m个值,均入栈。每次入栈均打印入栈返回结果。
  3. 输出栈顶元素,输出是否为空,输出size
  4. 使用Arrays.toString()输出内部数组中的值。
  5. 输入x,然后出栈x次,每次出栈均打印。
  6. 输出栈顶元素,输出是否为空,输出size
  7. 使用Arrays.toString()输出内部数组中的值。

思考

如果IntegerStack接口的实现类内部使用ArrayList来存储元素,怎么实现?测试代码需要进行什么修改?

import java.util.Arrays;
import java.util.Scanner;

interface IntegerStack {
    public Integer push(Integer item); //如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item
    public Integer pop();   //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
    public Integer peek();  //获得栈顶元素,如果为空,则返回null
    public boolean empty(); //如果为空返回true
    public int size();      //返回栈中元素个数
}

class ArrayIntegerStack implements IntegerStack{
    private Integer[] arr;
    private int top = 0;

    public ArrayIntegerStack(int n){
        arr = new Integer[n];
        Arrays.fill(arr, null);
    }

    public ArrayIntegerStack(){}

    @Override
    public String toString() {
        return Arrays.toString(arr);
    }

    @Override
    public Integer push(Integer item) {
        if (item == null || arr.length == top){
            return null;
        }
        arr[top++] = item;
        return item;
    }

    @Override
    public Integer pop() {
        if (top == 0){
            return null;
        }
        return arr[--top];
    }

    @Override
    public Integer peek() {
        if (top == 0){
            return null;
        }
        return arr[top - 1];
    }

    @Override
    public boolean empty() {
        return top == 0;
    }

    @Override
    public int size() {
        return top;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        ArrayIntegerStack ais = new ArrayIntegerStack(n);
        int m = scanner.nextInt();
        while(m-- > 0){
            int item = scanner.nextInt();
            System.out.println(ais.push(item));
        }
        System.out.println(ais.peek() + "," + ais.empty() + "," + ais.size());
        System.out.println(ais);
        int x = scanner.nextInt();
        while(x-- > 0){
            System.out.println(ais.pop());
        }
        System.out.println(ais.peek() + "," + ais.empty() + "," + ais.size());
        System.out.println(ais);
    }
}

7-5 jmu-Java-03面向对象基础-05-覆盖

Java每个对象都继承自Object,都有equals、toString等方法。
现在需要定义PersonOverride类并覆盖其toStringequals方法。

1. 新建PersonOverride类

a. 属性:String nameint ageboolean gender,所有的变量必须为私有(private)。

b. 有参构造方法,参数为name, age, gender

c. 无参构造方法,使用this(name, age,gender)调用有参构造方法。参数值分别为"default",1,true

d.toString()方法返回格式为:name-age-gender

e. equals方法需比较name、age、gender,这三者内容都相同,才返回true.

2. main方法

2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1。
2.2 输入n2,然后指定name age gender。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
2.3 输出persons1数组中的所有对象
2.4 输出persons2数组中的所有对象
2.5 输出persons2中实际包含的对象的数量
2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));输出PersonOverride的所有构造方法。

提示:使用ArrayList代替数组大幅复简化代码,请尝试重构你的代码。

import java.util.*;
 
 
class PersonOverride{
    private String name;
    private int age;
    private boolean gender;
    public PersonOverride() {
        this("default", 1, true);
    }
    public PersonOverride(String name,int age,boolean gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    @Override
    public String toString() {
        return this.name+"-"+this.age+"-"+this.gender;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o){
            return true;
        }
        if(o == null)
        {
            return false;
        }
        if (this.getClass() != o.getClass()){
            return false;
        }
        PersonOverride p = (PersonOverride) o;
        return Objects.equals((this.name), p.name) && this.gender == p.gender && this.age==p.age;
    }
}
public class Main{
    public static void main(String [] args){
       Scanner in=new Scanner(System.in);
        int n1 = in.nextInt();
        in.nextLine();
        PersonOverride[] persons1 = new PersonOverride[n1];
        for(int i=0;i<n1;i++) {
            persons1[i] = new PersonOverride();
        }
        int n2 = in.nextInt();
        in.nextLine();
        PersonOverride[] persons2 = new PersonOverride[n2];
        int len2=0;
        for(int i=0;i<n2;i++) {
            String name = in.next();
            int age = in.nextInt();
            boolean gender = in.nextBoolean();
            in.nextLine();
            PersonOverride p = new PersonOverride(name,age,gender);
            boolean flag = true;
            for(int j=0;j<len2;j++) {
                if(persons2[j].equals(p)) {
                    flag = false;
                    break;
                }
            }
            if(flag) {
                persons2[len2] = p;
                len2++;
            }
        }
        for(PersonOverride p:persons1) {
            System.out.println(p);
        }
        for(int i=0;i<len2;i++) {
            System.out.println(persons2[i]);
        }
        System.out.println(len2);
        System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
    }
}

三、踩坑心得

此题的难度适中,适合考察学生对面向对象设计原则和异常处理的理解。

在处理输入输出时,需要注意格式的要求,使用适当的分隔符进行分割。还要注意数组越界的问题,确保课程索引在合法范围内。

在解决问题时要选择合适的数据结构来存储和处理数据,例如使用列表和映射。

计算平均成绩时,需设计合适的算法处理课程成绩和权重,例如使用循环遍历计算总成绩。

编写代码时,要注意可读性和可维护性,使用合适的命名、注释和代码结构。可以考虑封装一些功能成函数,提高代码的可维护性。

四、改进建议

  1. 优化算法和数据结构:确保你所使用的算法和数据结构是高效的,并且能够满足程序的需求。在适当的情况下,可以考虑使用更高效的数据结构或算法,以提高程序的性能。

  2. 减少内存使用:Java程序在内存管理方面拥有一定的优势,但仍然需要注意内存使用情况。确保及时释放不再使用的对象,避免内存泄漏问题。可以使用一些内存分析工具来监测和解决内存问题。

  3. 多线程和并发处理:对于需要处理大量并发请求或需要执行长时间任务的程序,可以考虑使用多线程或并发处理来提高程序的性能和响应能力。使用Java提供的线程池和并发工具可以简化并发编程的复杂性。

  4. 异常处理:合理处理异常对于程序的稳定性和可靠性很重要。使用try-catch语句来捕获和处理异常,并根据具体情况选择适当的异常处理策略,如重试、回滚或记录错误信息。

  5. 代码重构:对于复杂或冗长的代码,可以考虑进行重构,以提高代码的可读性、易维护性和性能。使用设计模式和优化技巧来改善代码结构和性能。

  6. 性能测试和优化:定期进行性能测试,并使用性能分析工具来找出程序的瓶颈。根据测试结果进行适当的优化,以提高程序的响应时间和吞吐量。

  7. 代码规范和可维护性:遵循统一的代码规范和最佳实践,使代码易于阅读、理解和维护。使用注释和文档来解释代码的逻辑和功能。

  8. 引入第三方库和框架:合理使用一些优秀的第三方库和框架,可以提高开发效率和程序的功能性。但要注意选择稳定、活跃维护且符合项目需求的库和框架。

五、总结

作为一个学习Java的学生,我想总结一下我的学习经验和收获。

首先,学习Java需要打好基础。我首先学习了Java的基本语法,包括变量、数据类型、运算符、控制流等。这些基础知识是编写Java程序的基石,掌握了这些知识之后才能进一步深入学习。

其次,我学习了面向对象编程(OOP)的概念和Java中的实现。Java是一门面向对象的编程语言,理解面向对象的思想和原则对于编写高质量的Java程序至关重要。我学习了类、对象、继承、封装、多态等概念,并通过实践项目来巩固所学知识。

接着,我学习了Java的核心 API。Java提供了丰富的类库和API,掌握常用的API对于开发各类应用程序非常重要。我学习了字符串处理、集合框架、IO操作、多线程编程等常用的API,并通过实例来加深理解和熟悉使用。

此外,我也了解并学习了一些常用的开发工具和框架。例如,我使用过Eclipse和IntelliJ IDEA等集成开发环境来编写和调试Java程序,学习了使用Maven进行项目构建和依赖管理,熟悉了Spring框架的基本用法等。这些工具和框架能够提高开发效率和代码质量。

在学习Java的过程中,我也遇到了一些挑战。有时候遇到难以理解的概念或者错误的代码逻辑,但我通过查阅文档、阅读相关书籍、参考网上的教程和提问论坛等途径,最终都能够解决问题和理清思路。

总的来说,学习Java是一个不断探索和成长的过程。通过不断练习和实践,我越来越熟悉Java的语法和特性,并且能够编写出功能完善、可维护的Java程序。Java是一门广泛应用于企业级开发的编程语言,掌握它对于我的职业发展来说是非常有价值的。