面向对象程序设计第三次BLOG-3
前言:
这是本学期第三次博客作业,是对pta题目集7,8以及期末考试的总结。重点是对课程成绩统计程序2、3以及期末考试的总结。课程成绩统计2和3都是在课程成绩统计1的基础上的延伸,课程成绩统计程序2在第一次的基础上增加了实验课,课程成绩统计程序3在第二次的基础上修改了计算总成绩的方式,将成绩类的继承关系改为组合关系。第七次作业主要考察了知识点:类的应用,正则表达式,面向对象思想;第八次作业主要考察了知识点:类的应用,面向对象的思想,正则表达式;期末考试主要考察了知识点:类的应用,继承和多态的使用,抽象的使用。这几次作业的测试点都有些问题,没有全部答对。通过这几次作业的学习,完善了自己的Java知识,巩固了基础,对Java有了更深层次的了解。
nchu-software-oop-2023-下-7:
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
使用HashMap存储学生信息,并实现根据学号的检索功能
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
end之后输入某个学号,执行程序输出该生的详细信息
输出格式:
输出查询到的学生信息格式:学号+英文空格+姓名+英文空格+成绩
如果没有查询到,则输出:"The student "+查询的学号+" does not exist"
输入样例1:
在这里给出一组输入。例如:
20201107 张少军 83
20201116 李四 78
20201118 郑觉先 80
end
20201116
输出样例1:
在这里给出相应的输出。例如:
20201116 李四 78
输入样例2:
在这里给出一组输入。例如: 20201107 张少军 83 20201116 李四 78 20201118 郑觉先 80 end 20202316
输出样例2:
在这里给出相应的输出。例如:
The student 20202316 does not exist
import java.util.Scanner; import java.text.DecimalFormat; import java.util.Set; import java.util.HashSet; import java.util.Scanner; import static java.lang.System.exit; import java.util.*; public class Main { public static void main(String[] args) { HashMap<String, NameandScore> Student = new HashMap<>(); String message; NameandScore temp; Scanner in = new Scanner(System.in); while(!(message = in.nextLine()).equals("end")) { String [] keyandValue = message.split(" "); temp = new NameandScore(); temp.num = keyandValue[0]; temp.name = keyandValue[1]; temp.score = keyandValue[2]; Student.put(keyandValue[0],temp); } message = in.nextLine(); if(Student.containsKey(message)) { System.out.println(message+" "+Student.get(message).name+" "+Student.get(message).score); } else { System.out.println("The student "+message+" does not exist"); } } } class NameandScore { String num; String name; String score; } class SelectCsourse//选择课程 { SelectCsourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 } class SelectCourse//选择课程 { SelectCourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 }

此题较为容易,容易写出题解。
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
要求:使用HashMap存储学生信息。
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
输出格式:
按学号从大到小的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+成绩
输入样例:
在这里给出一组输入。例如:
20201124 张少军 83
20201136 李四 78
20201118 郑觉先 80
end
输出样例:
在这里给出相应的输出。例如:
20201136 李四 78 20201124 张少军 83 20201118 郑觉先 80
import java.util.Scanner; import java.text.DecimalFormat; import java.util.Set; import java.util.HashSet; import java.util.Scanner; import static java.lang.System.exit; import java.util.*; public class Main { public static void main(String[] args) { ArrayList<NameandScore> list = new ArrayList<>(); String message; NameandScore temp; Scanner in = new Scanner(System.in); while(!(message = in.nextLine()).equals("end")) { String [] keyAndValue = message.split(" "); temp = new NameandScore(); temp.num = keyAndValue[0]; temp.name = keyAndValue[1]; temp.score = keyAndValue[2]; list.add(temp); } Collections.sort(list); // Collections.reverseOrder(); for (NameandScore nameandScore : list) { System.out.println(nameandScore.num + " " + nameandScore.name + " " + nameandScore.score); } } } class SelectCsourse//选择课程 { SelectCsourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 } class SelectCourse//选择课程 { SelectCourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 } class NameandScore implements Comparable<NameandScore> { String num; String name; String score; @Override public int compareTo(NameandScore o) { if(this.num.compareTo(o.num) == 0) return 0; else if (this.num.compareTo(o.num)>0) return -1; else return 1; // return this.num.compareTo(o.num); } }
课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩的平均分
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修、实验
考核方式输入选项:考试、考察、实验
考试/考查课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
考试/考查课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩
实验次数至少4次,不超过9次
实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
以上信息的相关约束:
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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):

输入样例1:
在这里给出一组输入。例如:
java 实验 实验 20201103 张三 java 4 70 80 90 end
输出样例1:
在这里给出相应的输出。例如:
20201103 张三 : access mode mismatch 20201103 张三 did not take any exams java has no grades yet 202011 has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验 20201103 张三 java 3 70 80 90 end
输出样例2:
在这里给出相应的输出。例如:
wrong format
java has no grades yet
输入样例3:
在这里给出一组输入。例如:
java 必修 实验 20201103 张三 java 3 70 80 90 100 end
输出样例3:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例4:
在这里给出一组输入。例如:
java 必修 实验 20201103 张三 java 4 70 80 90 105 end
输出样例4:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
wrong format
输入样例5:
在这里给出一组输入。例如:
java 选修 考察 C语言 选修 考察 java实验 实验 实验 编译原理 必修 考试 20201101 王五 C语言 76 20201216 李四 C语言 78 20201307 张少军 编译原理 82 84 20201103 张三 java实验 4 70 80 90 100 20201118 郑觉先 java 80 20201328 刘和宇 java 77 20201220 朱重九 java实验 4 60 60 80 80 20201132 王萍 C语言 40 20201302 李梦涵 C语言 68 20201325 崔瑾 编译原理 80 84 20201213 黄红 java 82 20201209 赵仙芝 java 76 end
输出样例5:
在这里给出相应的输出。例如:
20201101 王五 76 20201103 张三 85 20201118 郑觉先 80 20201132 王萍 40 20201209 赵仙芝 76 20201213 黄红 82 20201216 李四 78 20201220 朱重九 70 20201302 李梦涵 68 20201307 张少军 83 20201325 崔瑾 82 20201328 刘和宇 77 C语言 65 65 java 78 78 java实验 77 编译原理 81 84 82 202011 70 202012 76 202013 77
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; import java.util.Scanner; import java.text.DecimalFormat; import java.util.Set; import java.util.HashSet; import java.util.Scanner; import static java.lang.System.exit; public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); MessageGetAndPrint messageGetAndPrint = new MessageGetAndPrint(); messageGetAndPrint.print = new Print(); for(;;){ String message = in.readLine(); if(message.equals("end")) { messageGetAndPrint.print.personPrint(messageGetAndPrint.students , messageGetAndPrint.courseSelections); messageGetAndPrint.print.coursePrint(messageGetAndPrint.courses , messageGetAndPrint.courseSelections); messageGetAndPrint.print.classPrint(messageGetAndPrint.classes , messageGetAndPrint.courseSelections); break; } messageGetAndPrint.getMessage(message); } } } class Class { private String classNum; HashMap<String , Student> students; Class(String classNum) { setClassNum(classNum); } public void setClassNum(String classNum) { this.classNum = classNum; } public String getClassNum() { return classNum; } public void addStudent(Student student) { students.put(student.getStudentNum() , student); } public void deleteStudent(String studentNum) { students.remove(studentNum); } } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } class Course { private String className; private int classQuality; private int assessmentMethodology; Course(String className , int classQuality , int assessmentMethodology) { setClassName(className); setClassQuality(classQuality); setAssessmentMethodology(assessmentMethodology); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public int getClassQuality() { return classQuality; } public void setClassQuality(int classQuality) { this.classQuality = classQuality; } public int getAssessmentMethodology() { return assessmentMethodology; } public void setAssessmentMethodology(int assessmentMethodology) { this.assessmentMethodology = assessmentMethodology; } } class CourseSelection { Student student; Course course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } class GradeA extends Grade { private int finalGrade; private int usualGrade; GradeA(int finalGrade , int usualGrade) { setFinalGrade(finalGrade); setUsualGrade(usualGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } public void setUsualGrade(int usualGrade) { this.usualGrade = usualGrade; } public int getUsualGrade() { return usualGrade; } @Override void getAllGrade() { allGrade = (int) (finalGrade*0.7+usualGrade*0.3); } } class GradeB extends Grade { private int finalGrade; GradeB(int finalGrade) { setFinalGrade(finalGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } @Override void getAllGrade() { allGrade = finalGrade; } } class GradeC extends Grade { ArrayList<Integer> usualGrades; GradeC(ArrayList<Integer> usualGrades) { this.usualGrades = usualGrades; } @Override void getAllGrade() { allGrade = 0; for(int x:usualGrades){ allGrade+=x; } allGrade = allGrade/usualGrades.size(); } } class Print { public void personPrint(HashMap<String , Student> students , ArrayList<CourseSelection> courseSelections) { Set<String> set = students.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for (CourseSelection courseSelection : courseSelections) { if (students.get(key).getStudentNum().equals(courseSelection.student.getStudentNum())) { if(y == -1) y = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" did not take any exams"); continue; } x = x / y; System.out.println(students.get(key).getStudentNum()+" "+students.get(key).getName()+" "+x); } } class dish { //特色菜的属性:菜名、口味、价格 String name; String taste; int price; public dish(String name, String taste, int price) { this.name = name; this.taste = taste; this.price = price; } public dish(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public String getTaste() { return taste; } public int getPrice() { return price; } public void setName(String name) { this.name = name; } public void setTaste(String taste) { this.taste = taste; } public void setPrice(int price) { this.price = price; } } class MyCompar2ator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { // TODO Auto-generated method stub if(arg0.length()>arg1.length()) return arg0.compareToIgnoreCase(arg1); else if(arg0.length()==arg1.length()) return arg0.compareToIgnoreCase(arg1); else return arg0.compareToIgnoreCase(arg1); } } public void coursePrint(HashMap<String , Course> courses , ArrayList<CourseSelection> courseSelections) { List<String> list = courses.keySet().stream().collect(Collectors.toList()); Collections.sort(list , new SoftName()); for(String key:list) { int x = 0 , y = -1 , f = 0 , u = 0 , uy = -1 , s = -1; for (CourseSelection courseSelection : courseSelections) { if (courses.get(key).getClassName().equals(courseSelection.course.getClassName())) { if(y == -1) y = 0; if(courses.get(key).getAssessmentMethodology() == 1 && uy == -1) uy = 0; if(courses.get(key).getAssessmentMethodology() == 3 && s == -1) s = 0; courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; if(courseSelection.grade instanceof GradeA) { f += ((GradeA) courseSelection.grade).getFinalGrade(); u += ((GradeA) courseSelection.grade).getUsualGrade(); uy++; } if(courseSelection.grade instanceof GradeB) { f += ((GradeB) courseSelection.grade).getFinalGrade(); } y++; } } if(y == -1) { System.out.println(courses.get(key).getClassName()+" has no grades yet"); continue; } x = x/y; f = f/y; if(s == 0) { System.out.println(courses.get(key).getClassName()+" "+x); continue; } if(uy == -1) { System.out.println(courses.get(key).getClassName()+" "+f+" "+x); } if(uy != -1) { u = u/uy; System.out.println(courses.get(key).getClassName()+" "+u+" "+f+" "+x); } } } public void classPrint(HashMap<String , Class> classes , ArrayList<CourseSelection> courseSelections) { Set<String> set = classes.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object key:arr) { int x = 0 , y = -1; for(CourseSelection courseSelection : courseSelections) { if(classes.get(key).students.containsKey(courseSelection.student.getStudentNum())) { if(y == -1) { y = 0; } courseSelection.grade.getAllGrade(); x += courseSelection.grade.allGrade; y++; } } if(y == -1) { System.out.println(classes.get(key).getClassNum()+" has no grades yet"); continue; } x = x/y; System.out.println(classes.get(key).getClassNum()+" "+x); } } public void wrongFormat() { System.out.println("wrong format"); } public void courseExist(String name) { System.out.println(name+" does not exist"); } public void courseMatch(String studentNum , String studentName) { System.out.println(studentNum+" "+studentName+" : access mode mismatch"); } public void courseMatch(String name) { System.out.println(name+" : course type & access mode mismatch"); } static class SoftName implements Comparator<String>{ public int compare(String name1 , String name2) { Comparator<Object> compare = Collator.getInstance(Locale.CHINA); return compare.compare(name1 , name2); } } } class SelectCourse//选择课程 { SelectCourse(Student student,Course courses,int great) { this.student = student; this.courses = courses; this.great = great; } Student student;//学生 Course courses;//课程 int great;//分数 } class ClassOfStudent//班级 { ClassOfStudent(String classNumber) { this.classNumber = classNumber; } String classNumber;//班级号 HashMap<String,Student> studentHashMap = new HashMap<>();//课堂由学生组成 } class User { int num; String name; String phone; int price; public User(int num, String name, String phone, int price) { this.num = num; this.name = name; this.phone = phone; this.price = price; } public String getName() { return name; } public String getPhone() { return phone; } public int getPrice() { return price; } public int getNum() { return num; } public void setName(String name) { this.name = name; } public void setPhone(String phone) { this.phone = phone; } public void setPrice(int price) { this.price = price; } public void setNum(int num) { this.num = num; } } class MessageGetAndPrint { Print print; HashMap<String , Class> classes = new HashMap<>(); HashMap<String , Student> students = new HashMap<>(); HashMap<String , Course> courses = new HashMap<>(); ArrayList<CourseSelection> courseSelections = new ArrayList<>(); public void getMessage(String getInput) { String[] message = getInput.split(" "); if(getInput.matches("^(\\S{1,10})( )(必修)$")) { int i = 1, j = 1; if(courses.containsKey(message[0])) { return; } Course course = new Course(message[0], i, j); courses.put(message[0], course); return; } if(getInput.matches("^(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)$")) { int i = 0, j = 0; if(message[1].equals("必修")) { i = 1; } if(message[1].equals("选修")) { i = 2; } if(message[1].equals("实验")) { i = 3; } if(message[2].equals("考试")) { j = 1; } if(message[2].equals("考察")) { j = 2; } if(message[2].equals("实验")) { j = 3; } if(i == 1 && j != 1) { print.courseMatch(message[0]); return; } if(i == 3 && j != 3) { print.courseMatch(message[0]); return; } if(i != 3 && j == 3) { print.courseMatch(message[0]); return; } if(courses.containsKey(message[0])) { return; } Course course = new Course(message[0], i, j); courses.put(message[0], course); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)( )([0-9]|[1-9][0-9]|100)$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).students.put(message[0], student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 1) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[4]); int usualGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeA(finalGrade , usualGrade); courseSelections.add(courseSelection); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|10{2})$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 2) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); int finalGrade = Integer.parseInt(message[3]); courseSelection.grade = new GradeB(finalGrade); courseSelections.add(courseSelection); return; } if(getInput.matches("^([0-9]{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((([0-9]|[1-9][0-9]|100)( ))+)([0-9]|[1-9][0-9]|100)$")) { for(CourseSelection courseSelection:courseSelections) { if(courseSelection.student.getStudentNum().equals(message[0])&&courseSelection.student.getName().equals(message[1])&&courseSelection.course.getClassName().equals(message[2])) { return; } } Student student = new Student(message[1], message[0]); students.put(message[0] , student); String classNum = message[0].substring(0 , 6); if(!classes.containsKey(classNum)) { Class aClass = new Class(classNum); classes.put(classNum , aClass); classes.get(classNum).students = new HashMap<>(); } classes.get(classNum).addStudent(student); if(!courses.containsKey(message[2])) { print.courseExist(message[2]); return; } if(courses.get(message[2]).getAssessmentMethodology() != 3) { print.courseMatch(message[0] , message[1]); return; } int usualNum = Integer.parseInt(message[3]); if(message.length-4 != usualNum) { print.courseMatch(message[0] , message[1]); return; } CourseSelection courseSelection = new CourseSelection(); courseSelection.student = student; courseSelection.course = courses.get(message[2]); ArrayList<Integer> usualGrades = new ArrayList<>(); for(int i = 1;i <= usualNum;i++) { usualGrades.add(Integer.parseInt(message[3+i])); } courseSelection.grade = new GradeC(usualGrades); courseSelections.add(courseSelection); return; } print.wrongFormat(); } }
类设计如下:
Main类:包含主方法,用于读取输入并调用systemin类的方法。
score抽象类:包含总分、平时成绩和期末成绩属性及对应的getter方法。其中总分属性为抽象方法,具体实现在其子类中。
Testscore类:继承自score类,实现了总分计算方法,其中总分由平时成绩和期末成绩按照一定比例计算得出。
Otherscore类:继承自score类,实现了总分计算方法,总分即为期末成绩。
Course类:表示课程,包含课程名称、课程类型和考核方式属性,以及对应的getter方法。
Student类:表示学生,包含学号和姓名属性,以及对应的getter方法。
SelectCourse类:表示选课情况,包含课程、学生和成绩属性,以及对应的getter和setter方法。
systemin类:包含一系列方法,用于处理输入数据并进行相应的操作,如添加课程、学生、选课信息等,还提供了获取平均成绩的方法。
Imatch类:提供了一些静态方法,用于判断输入数据的格式是否正确。
题目描述
编辑
输入多个学生的成绩信息,包括:学号、姓名、数学成绩、物理成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
要求:使用ArrayList存储学生信息。
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+数学成绩+英文空格+物理成绩
以“end”为输入结束标志
输出格式:
按数学/物理成绩之和从高到低的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+数学/物理成绩之和
成绩相同的情况,按输入的先后顺序输出。
输入样例:
在这里给出一组输入。例如:
20201124 张少军 83 75
20201136 李四 78 86
20201118 郑觉先 80 62
end
输出样例:
在这里给出相应的输出。例如:
20201136 李四 164 20201124 张少军 158 20201118 郑觉先 142

- 输入n,然后连续输入n个身份证号。
- 然后根据输入的是sort1还是sort2,执行不同的功能。输入的不是sort1或sort2,则输出
exit并退出。
输入sort1,将每个身份证的年月日抽取出来,按年-月-日格式组装,然后对组装后的年-月-日升序输出。
输入sort2,将所有身份证按照里面的年月日升序输出。
注意:处理输入的时候,全部使用Scanner的nextLine()方法,以免出错。
输入样例:
6 410425198309308225 320203197206115011 431227196108033146 330226196605054190 34080019810819327X 320111197112301539 sort1 sort2 e
输出样例:
1961-08-03 1966-05-05 1971-12-30 1972-06-11 1981-08-19 1983-09-30 431227196108033146 330226196605054190 320111197112301539 320203197206115011 34080019810819327X 410425198309308225 exit
import java.util.Arrays; import java.util.Scanner; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; import java.util.Scanner; import java.text.DecimalFormat; public class Main { public static void main(String[] args) { Scanner sc=new Scanner (System.in); int n; n=sc.nextInt(); String s[]=new String[n]; //装身份证号的 String birth[]=new String[n]; //这个是装生日的 String str; for(int i=0;i<n;i++) { s[i]=sc.next(); //并没有用nextLine()感觉那样写没有这么写简单 } while(true) { str=sc.next(); if(str.equals("e")) { System.out.println("exit"); break; }else if(str.equals("sort1")) { for(int i=0;i<n;i++) { birth[i]=s[i].substring(6,10 )+'-'+ s[i].substring(10, 12)+'-'+s[i].substring(12, 14); } Arrays.sort(birth); //生日先升序 for(int i=0;i<n;i++) { System.out.println(birth[i]); } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } }else if(str.equals("sort2")) { //生日先升序排一下 for(int i=0;i<n;i++) { birth[i]=s[i].substring(6,10 )+ s[i].substring(10, 12)+s[i].substring(12, 14); class CourseSelection { int student; int course; int grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } } Arrays.sort(birth); for(int i=0;i<n;i++) { for(int j=0;j<n;j++){ if(s[j].contains(birth[i])) { System.out.println(s[j]); break; } } } } } } }

课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):

输入样例1:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
输入样例2:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2
end
输出样例2:
在这里给出相应的输出。例如:
java : number of scores does not match
输入样例3:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.1
end
输出样例3:
在这里给出相应的输出。例如:
java : weight value error
输入样例4:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100
end
输出样例4:
在这里给出相应的输出。例如:
20201116 张三 86
java 86
202011 86
输入样例5:
在这里给出一组输入。例如:
java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100 80
end
输出样例5:
在这里给出相应的输出。例如:
20201116 张三 : access mode mismatch 20201116 张三 did not take any exams java has no grades yet 202011 has no grades yet
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; } class Great//成绩 { Great(){} int commonGreat;//平时成绩 int lastTestGreat;//期末成绩 int allGreat;//总成绩(需要计算) } class SubItemGrades { ArrayList<Integer> grades = new ArrayList<>(); ArrayList<Float> subItem = new ArrayList<>(); } //定义一个山羊类,和上面一样 class MyCompar2ator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { // TODO Auto-generated method stub if(arg0.length()>arg1.length()) return arg0.compareToIgnoreCase(arg1); else if(arg0.length()==arg1.length()) return arg0.compareToIgnoreCase(arg1); else return arg0.compareToIgnoreCase(arg1); } } class SelectCsourse//选择课程 { SelectCsourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 } class SelectCourse//选择课程 { SelectCourse(int student,int courses,int great) { this.student = student; this.courses = courses; this.great = great; } int student;//学生 int courses;//课程 int great;//分数 } class NameandScore implements Comparable<NameandScore> { String num; String name; String score; @Override public int compareTo(NameandScore o) { if(this.num.compareTo(o.num) == 0) return 0; else if (this.num.compareTo(o.num)>0) return -1; else return 1; // return this.num.compareTo(o.num); } } 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); } }
类设计如下:
Choose类:表示学生选择的课程和成绩信息,其中包含Course、Student和Score对象。表示了学生选课和成绩的关联关系。
Course类:表示课程信息,包含课程名称、性质、考试方式等属性。与Choose类关联,表示了课程和学生选课之间的关系。
Student类:表示学生信息,包含学号和姓名。与Choose类关联,表示了学生和选课成绩之间的关系。
myClass类:表示班级信息,包含班级ID和学生列表。与Student类关联,表示了班级和学生之间的关系。
ParseInput类:包含对输入数据的解析和处理方法,包含了对Course、Student和Choose的管理和操作。
Score类及其子类:表示学生成绩信息,包含了不同类型的成绩计算方式,与Choose类关联,表示了学生成绩的具体信息。
Main类:包含了程序的入口点main方法,用于接收用户输入的数据,并调用ParseInput类进行处理。



定义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方法说明
- 输入n,建立可包含n个元素的ArrayIntegerStack对象
- 输入m个值,均入栈。每次入栈均打印入栈返回结果。
- 输出栈顶元素,输出是否为空,输出size
- 使用Arrays.toString()输出内部数组中的值。
- 输入x,然后出栈x次,每次出栈均打印。
- 输出栈顶元素,输出是否为空,输出size
- 使用Arrays.toString()输出内部数组中的值。
思考
如果IntegerStack接口的实现类内部使用ArrayList来存储元素,怎么实现?测试代码需要进行什么修改?
输入样例
5 3 1 2 3 2
输出样例
1 2 3 3,false,3 [1, 2, 3, null, null] 3 2 1,false,1 [1, 2, 3, null, null]
import java.util.Arrays; import java.util.Comparator; 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]; } class CourseSelection { Student student; int course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } @Override public Integer peek() { if (top == 0){ return null; } return arr[top - 1]; } class MyCompar2ator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { // TODO Auto-generated method stub if(arg0.length()>arg1.length()) return arg0.compareToIgnoreCase(arg1); else if(arg0.length()==arg1.length()) return arg0.compareToIgnoreCase(arg1); else return arg0.compareToIgnoreCase(arg1); } } @Override public boolean empty() { return top == 0; } class Student { private String name; private String studentNum; Student(String name , String studentNum) { setName(name); setStudentNum(studentNum); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStudentNum() { return studentNum; } public void setStudentNum(String studentNum) { this.studentNum = studentNum; } } @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); } }

期末考试:
编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。
类结构如下图所示(参考):

试编程完成如上类设计,主方法源码如下(可直接拷贝使用):
public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); double side = input.nextDouble(); display(new Cube(side)); display(new RegularPyramid(side)); }
其中,display(Solid solid)方法为定义在Main类中的静态方法,作用为体现程序的多态性。
注:正三棱锥的体积计算公式为底面积*高/3。
输入格式:
输入一个实型数,分别作为正方体的边长和正三棱锥的边长。
输出格式:
分别输出正方体的表面积、体积以及正棱锥的表面积和体积。保留两位小数,建议使用String.format(“%.2f”,value)
进行小数位数控制。
输入样例:
在这里给出一组输入。例如:
2.5
s
输出样例:
在这里给出相应的输出。例如:
37.50 15.63 10.83 1.84
import java.util.Scanner; import java.util.Scanner; import java.util.stream.Collectors; import java.util.Scanner; import java.text.DecimalFormat; import java.util.Set; import java.util.HashSet; import java.util.Scanner; import java.util.Scanner; abstract class Solid { abstract double getSurfaceArea(); abstract double getVolume(); } class Cube extends Solid { private double side; Cube(double side) { this.side = side; } @Override double getSurfaceArea() { return 6 * side * side; } @Override double getVolume() { return side * side * side; } } class CourseSelection { int student; int course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } class Tetrahedron extends Solid { private double side; Tetrahedron(double side) { this.side = side; } @Override double getSurfaceArea() { return Math.sqrt(3) * side * side; } @Override double getVolume() { return Math.sqrt(2) * side * side * side / 12; // 四面体的体积计算公式 } } class CourseSewlection { int student; int course; Grade grade; } abstract class Grwade { int allGrade; abstract void getAllGrade(); } public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double side = input.nextDouble(); display(new Cube(side)); display(new Tetrahedron(side)); // 将正三棱锥改为四面体 } public static void display(Solid solid) { System.out.println(String.format("%.2f", solid.getSurfaceArea())); System.out.println(String.format("%.2f", solid.getVolume())); } }

在魔方问题的基础上,重构类设计,实现列表内魔方的排序功能(按照魔方的体积进行排序)。
提示:题目中RubikCube类要实现Comparable接口。
其中,Main类源码如下(可直接拷贝使用):
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); String color; int layer; double side; RubikCube cube; ArrayList<RubikCube> list = new ArrayList<>(); int choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://SquareCube color = input.next(); layer = input.nextInt(); side = input.nextDouble(); cube = new SquareCube(color, layer,new Cube(side)); list.add(cube); break; case 2://RegularPyramidCube color = input.next(); layer = input.nextInt(); side = input.nextDouble(); cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); list.add(cube); break; } choice = input.nextInt(); } list.sort(Comparator.naturalOrder());//正向排序 for(int i = 0; i < list.size(); i++) { System.out.print(list.get(i).getColor() + " " + String.format("%.2f", list.get(i).getArea()) + " " + String.format("%.2f", list.get(i).getVolume()) ); System.out.println(""); } } }
输入格式:
输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)
魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长
..循环..
输出格式:
按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。
输入样例:
在这里给出一组输入。例如:
1 blue 3 4.5 2 red 4 2.1 1 yellow 5 2.3 2 black 4 9.42 1 white 4 5.4423 0
输出样例:
在这里给出相应的输出。例如:
red 122.21 69.85 yellow 793.50 1520.88 blue 1093.50 2460.38 black 2459.14 6304.73 white 2843.39 10316.38
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Scanner; import java.util.Scanner; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; import java.util.Scanner; import java.text.DecimalFormat; class MagicCube { private String color; private int order; private double unitLength; private String type; public MagicCube(String color, int order, double unitLength, String type) { this.color = color; this.order = order; this.unitLength = unitLength; this.type = type; } public double calculateSurfaceArea() { if (type.equals("正方体")) { return 6 * Math.pow(order * unitLength, 2); } else if (type.equals("正四面体")) { return Math.sqrt(3) * Math.pow(order * unitLength, 2); } else { return 0; } } public double calculateVolume() { if (type.equals("正方体")) { return Math.pow(order * unitLength, 3); } else if (type.equals("正四面体")) { return Math.sqrt(2) / 12 * Math.pow(order * unitLength, 3); } else { return 0; } } public String getColor() { return color; } } class CourseSelection { int student; int course; Grade grade; } abstract class Grade { int allGrade; abstract void getAllGrade(); } class GradeA extends Grade { private int finalGrade; private int usualGrade; GradeA(int finalGrade , int usualGrade) { setFinalGrade(finalGrade); setUsualGrade(usualGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } public void setUsualGrade(int usualGrade) { this.usualGrade = usualGrade; } public int getUsualGrade() { return usualGrade; } @Override void getAllGrade() { allGrade = (int) (finalGrade*0.7+usualGrade*0.3); } } class GradeB extends Grade { private int finalGrade; GradeB(int finalGrade) { setFinalGrade(finalGrade); } public void setFinalGrade(int finalGrade) { this.finalGrade = finalGrade; } public int getFinalGrade() { return finalGrade; } @Override void getAllGrade() { allGrade = finalGrade; } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); List<MagicCube> cubeList = new ArrayList<>(); while (true) { int cubeType = scanner.nextInt(); if (cubeType == 0) { break; } String cubeColor = scanner.next(); int cubeOrder = scanner.nextInt(); double unitLength = scanner.nextDouble(); MagicCube cube = new MagicCube(cubeColor, cubeOrder, unitLength, cubeType == 1 ? "正方体" : "正四面体"); cubeList.add(cube); } Collections.sort(cubeList, new Comparator<MagicCube>() { @Override public int compare(MagicCube cube1, MagicCube cube2) { double volume1 = cube1.calculateVolume(); double volume2 = cube2.calculateVolume(); if (volume1 < volume2) { return -1; } else if (volume1 > volume2) { return 1; } else { return 0; } } }); for (MagicCube cube : cubeList) { System.out.print(cube.getColor()); System.out.printf(" %.2f ", cube.calculateSurfaceArea()); System.out.printf("%.2f\n", cube.calculateVolume()); } } }
注意题中应该按照四面体计算。

前亚利桑那州境内的一位步枪销售商销售密苏里州制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是销售商在一个月内可销售70个枪机、80个枪托和90个枪管。
根据每个月的销售情况,计算销售商的佣金(提成)算法如下:
-
不到(含)1000美元的部分为10%;
-
1000(含)~1800美元的部分为15%;
-
超过1800美元的部分为20%。
佣金程序生成月份销售报告,汇总销售商的销售总额和佣金。
编程要求:必须符合面向对象编程,且保证类设计的单一职责模式,使用面向过程编程判定0分。
提示:可以设置一个销售订单类。参考类图如下:

输入格式:
输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。
输出格式:
分别输出销售商在该月的销售额和佣金,中间用空格分开。
输入样例1:
在这里给出一组输入。例如:
30 40 50
输出样例1:
在这里给出相应的输出。例如:
3800.00 620.00
输入样例2:
在这里给出一组输入。例如:
88 56 98
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
import java.util.Scanner; import java.util.Scanner; import java.text.Collator; import java.util.*; import java.util.stream.Collectors; import java.util.Scanner; import java.text.DecimalFormat; class SalesOrder { int gunLocks; int gunStocks; int gunBarrels; SalesOrder(int gunLocks, int gunStocks, int gunBarrels) { this.gunLocks = gunLocks; this.gunStocks = gunStocks; this.gunBarrels = gunBarrels; } double calculateSalesAmount() { double lockPrice = 45.0; double stockPrice = 30.0; double barrelPrice = 25.0; return gunLocks * lockPrice + gunStocks * stockPrice + gunBarrels * barrelPrice; } class MyCompar3ator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { // TODO Auto-generated method stub if(arg0.length()>arg1.length()) return arg0.compareToIgnoreCase(arg1); else if(arg0.length()==arg1.length()) return arg0.compareToIgnoreCase(arg1); else return arg0.compareToIgnoreCase(arg1); } } class MyCompar2ator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { // TODO Auto-generated method stub if(arg0.length()>arg1.length()) return arg0.compareToIgnoreCase(arg1); else if(arg0.length()==arg1.length()) return arg0.compareToIgnoreCase(arg1); else return arg0.compareToIgnoreCase(arg1); } } double calculateCommission() { double salesAmount = calculateSalesAmount(); if (salesAmount <= 1000) { return salesAmount * 0.1; } else if (salesAmount <= 1800) { return 1000 * 0.1 + (salesAmount - 1000) * 0.15; } else { return 1000 * 0.1 + 800 * 0.15 + (salesAmount - 1800) * 0.2; } } } public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int gunLocks = input.nextInt(); int gunStocks = input.nextInt(); int gunBarrels = input.nextInt(); if (gunLocks >= 1 && gunLocks <= 70 && gunStocks >= 1 && gunStocks <= 80 && gunBarrels >= 1 && gunBarrels <= 90) { SalesOrder salesOrder = new SalesOrder(gunLocks, gunStocks, gunBarrels); double salesAmount = salesOrder.calculateSalesAmount(); double commission = salesOrder.calculateCommission(); System.out.printf("%.2f %.2f\n", salesAmount, commission); } else { System.out.println("Wrong Format"); } } }

此题要注意题干中较为隐晦限制条件,限制数量至少为一。
踩坑心得:
1.在开始编写代码之前,先进行合理的类设计是非常重要的。良好的类设计应该遵循单一职责原则、开放封闭原则、依赖倒置原则等基本原则。
2.在选择数据结构和数据类型时,要根据实际需求进行合理选择。例如,在菜单类中使用ArrayList来管理菜品列表,在订单记录类中使用HashMap来存储订单信息。
3.在编写代码时,要考虑可能出现的异常情况,并进行合理的异常处理。这样可以增加程序的健壮性和可靠性。
4.在编写代码时,要注意良好的代码风格和格式。使用适当的缩进、注释和命名规范,可以提高代码的可读性和可理解性。
5.在编写代码后,进行测试和调试是非常重要的。通过单元测试和集成测试,可以验证代码的正确性,并发现潜在的问题和bug。
总结:
总的来说,这次实验对我的面向对象编程能力和代码设计能力有了很大的提升。
首先,我从最基础的语法开始学习,掌握了 Java 的关键字、数据类型、运算符等基本概念。通过不断的练习和实践,我熟悉了 Java 的编码规范和命名规范,形成了良好的编码习惯。
其次,我深入学习了面向对象编程的思想,包括类、对象、封装、继承和多态等概念。我意识到面向对象编程可以使代码更加模块化、可扩展和可维护,这对于编写复杂的软件系统至关重要。
最后,学习编程语言最重要的还是熟练,就是熟能生巧,只有通过不断地学习,不断地改进,才能真正地提升自己,一定要多实践。
浙公网安备 33010602011771号