一、前言
对于这几次的课程成绩统计程序的PTA的大作业来说,我认为这几次的作业是有共同之处的
·课程成绩统计程序一是该系列的开山之篇,其实现了对课程信息的录入已经对学生,班级,课程方面的信息处理,让我们能够更加直观的看出学生,班级,课程的详情
·课程成绩统计程序二是在课程成绩统计程序一的基础上增加了实验课程以及新的成绩计算方式
·课程成绩统计程序三是在课程成绩统计程序二的基础上增加了对于实验课程计算成绩时候的比重分配以及课程成绩计算的方式
二、设计与分析
PTA6:
本题目集只有一题,课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃
第一步根据题目构建相应的类
class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修)"; static String checkCourseTypeMatching = "(考试|考察)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + 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) { //System.out.println(match); return s.matches(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } }
上述的是构建字符串解析类,是对输入的字符串进行相应的解析,判断是进行增加课程信息还是增加学生的选课的信息,并调用相应的方法
class Course implements Comparable<Course> { String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 int totalMark;//这个是这门课的分数 int normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 int finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type) { this.name = name; this.mode = mode; this.type = type; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(int normalMark,int finallyMark) { this.normalMark +=normalMark; this.finallyMark +=finallyMark; this.chooseCount++; } void setMark(int finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.normalMark == 0) { System.out.println(this.name+" "+this.finallyMark+" "+this.finallyMark); } else { System.out.println(this.name+" "+this.normalMark+" "+this.finallyMark+" "+this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = (int) (this.normalMark*0.3+this.finallyMark*0.7); } } }
上述的代码是课程类,该类包括了课程的基本信息,例如课程名称,课程性质,课程的考核方式等等,该类中的setMark()和setGrade()方法分别是对所选该门课程的学生的成绩进行累加和对总体的成绩进行计算平均分,courseShow()方法是对该课程的成绩信息进行输出,此外这个类实现了Comparable接口实现了对按课程成绩平均分进行从小到大排序的功能
class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { String num; int totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(int mark1,int mark2) { this.totalMark += mark1*0.3 +mark2 *0.7; } void setMark(int mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num+" has no grades yet"); } else { System.out.println(this.num+" "+this.totalMark); } } void setGrade() { if(this.studentNum ==0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } }
课程谱类,该类记录的是我们先前输入进去的课程信息,方便后续学生计算成绩时候,按照该类去判断学生信息输入是否按照规定输入,如果不是按照规定输入的话,那么就要输出Wrong Format
class Class implements Comparable<Class> { String num; int totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(int mark1,int mark2) { this.totalMark += mark1*0.3 +mark2 *0.7; } void setMark(int mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num+" has no grades yet"); } else { System.out.println(this.num+" "+this.totalMark); } } void setGrade() { if(this.studentNum ==0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } }
以上的代码是班级类,该类记录的信息包括班级号和学生的信息,以及班级的平均分,同样的这个类也是实现了Comparable接口,实现了按照班级平均分从小到大排序的功能,这个类也是包含了setMark()和setGrade()方法分别实现的是对学生成绩的累加和对平均分的计算,最后通过调用classShow()方法输出班级的成绩信息
class Student implements Comparable<Student> { String num; String name; int mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(int mark1,int mark2) { this.mark += (int) (mark1*0.3 + mark2*0.7); } void setMark(int mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+this.mark); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } }
上述的代码是学生类,该类包括了学生的基本信息,也包括了学生所选的课程信息,同样的这个类也是实现了Comparable接口,实现了按照学生学号从小到大排序的功能,这个类也是包含了setMark()和setGrade()方法分别实现的是对学生各科成绩的累加和对平均分的计算,最后通过调用stuShow()方法输出班级的成绩信息
class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0 : System.out.println("wrong format");break; case 1 : addCourse(a);break; case 2 : addScore(a);break; } } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { if (a.matches("\\S* 必修* 考察"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2]); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) { String [] b = a.split(" "); if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore, examScore); currentClass.setMark(normalScore, examScore); currentCourse.setMark(normalScore, examScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { Collections.sort(students); for(Student s : students) { s.stuShow(); } } void showClass() { Collections.sort(classes); for(Class s : classes) { s.classShow(); } } void showCourse() { Collections.sort(coursemenu.classmenu); for(Course s : coursemenu.classmenu) { s.courseShow(); } } }
该类是主类,学校类,这个类里面包括了开设的课程和开设的班级,班级里面有学生,在该类里面,通过各函数的相互调用实现了对输入的字符串的信息处理
第二步将各类结合,最终实现的代码如下:
import java.text.Collator; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); School school = new School(); String a; while(!(a=in.nextLine()).equals("end")) { school.parseInput(a); } school.showStudent(); school.showCourse(); school.showClass(); } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修)"; static String checkCourseTypeMatching = "(考试|考察)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + 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) { //System.out.println(match); return s.matches(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } } class Course implements Comparable<Course> { String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 int totalMark;//这个是这门课的分数 int normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 int finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type) { this.name = name; this.mode = mode; this.type = type; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(int normalMark,int finallyMark) { this.normalMark +=normalMark; this.finallyMark +=finallyMark; this.chooseCount++; } void setMark(int finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.normalMark == 0) { System.out.println(this.name+" "+this.finallyMark+" "+this.finallyMark); } else { System.out.println(this.name+" "+this.normalMark+" "+this.finallyMark+" "+this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = (int) (this.normalMark*0.3+this.finallyMark*0.7); } } } class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { String num; int totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(int mark1,int mark2) { this.totalMark += mark1*0.3 +mark2 *0.7; } void setMark(int mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num+" has no grades yet"); } else { System.out.println(this.num+" "+this.totalMark); } } void setGrade() { if(this.studentNum ==0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } } class Student implements Comparable<Student> { String num; String name; int mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(int mark1,int mark2) { this.mark += (int) (mark1*0.3 + mark2*0.7); } void setMark(int mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+this.mark); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } } class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0 : System.out.println("wrong format");break; case 1 : addCourse(a);break; case 2 : addScore(a);break; } } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { if (a.matches("\\S* 必修* 考察"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2]); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) { String [] b = a.split(" "); if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore, examScore); currentClass.setMark(normalScore, examScore); currentCourse.setMark(normalScore, examScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { Collections.sort(students); for(Student s : students) { s.stuShow(); } } void showClass() { Collections.sort(classes); for(Class s : classes) { s.classShow(); } } void showCourse() { Collections.sort(coursemenu.classmenu); for(Course s : coursemenu.classmenu) { s.courseShow(); } } }
实现的结果:
PTA7:
本题目集包括了4道题,分别是容器-HashMap-检索,容器-HashMap-排序,课程成绩统计程序-2, 动物发声模拟器(多态)
第一题:容器-HashMap-检索,先上网搜索HashMap的实现思路,其实就是键值对的使用,我的代码
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; }
第二题: 容器-HashMap-排序,实际是在使用键值对的基础上实现了Comparable接口从而实现对学生信息按照学号从大到小进行排序,我的代码
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 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,对于这道题的话,我的代码设计思路是同课程成绩统计程序-1的,在构建类的基础上对相应类进行了相应的修改,我的代码设计思路如下:
class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkCourseTypeMatching = "(考试|考察|实验)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; public static int matchingInput(String s) { String [] s1 = s.split(" "); if(s1.length>5) { return 2;//在这里直接返回对应的值 } //这里偷一下懒 不选择正则表达式 直接根据字符串的长度去判断 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(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } }
该类的作用是同课程成绩统计程序-1中的类,只是对于输入的是实验的课程和学生选课为实验课进行了相应的判断,其他的功能是大致相同的
class Course implements Comparable<Course> { String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 int totalMark;//这个是这门课的分数 int normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 int finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type) { this.name = name; this.mode = mode; this.type = type; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(int normalMark,int finallyMark) { this.normalMark +=normalMark; this.finallyMark +=finallyMark; this.chooseCount++; } void setMark(int finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.type.equals("实验")) { System.out.println(this.name+" "+this.finallyMark); return ; } if(this.normalMark == 0) { System.out.println(this.name+" "+this.finallyMark+" "+this.finallyMark); } else { System.out.println(this.name+" "+this.normalMark+" "+this.finallyMark+" "+this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = (int) (this.normalMark*0.3+this.finallyMark*0.7); } } } class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { boolean hasChooseErrorStudents; String num; int totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; this.hasChooseErrorStudents = false; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(int mark1,int mark2) { this.totalMark += mark1*0.3 +mark2 *0.7; } void setMark(int mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.hasChooseErrorStudents) { return ; } if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num + " has no grades yet"); } else { System.out.println(this.num+" "+this.totalMark); } } void setGrade() { if(this.studentNum == 0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).hasChooseError) { this.hasChooseErrorStudents = true; return ; } if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } } class Student implements Comparable<Student> { boolean hasChooseError; String num; String name; int mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; this.hasChooseError = false; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(int mark1,int mark2) { this.mark += (int) (mark1*0.3 + mark2*0.7); } void setMark(int mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.hasChooseError == true) { return ; } if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+this.mark); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } }
以上代码中所包含的类是和课程成绩统计程序-1的功能是大致相同的,类中的方法也是与课程成绩统计程序-1中对于类的功能相同,在这里我就不进行过多的赘述了
class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0: System.out.println("wrong format");break; case 1: addCourse(a);break; case 2: addScore(a);break; } } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { if(a.matches("\\S* 实验* 实验"))//匹配成功 { currentCourse = new Course(b[0],b[1],b[2]); coursemenu.addCourse(currentCourse); return ;//结束当前的函数 }else if(a.matches("\\S* 实验* 考试")||a.matches("\\S* 实验* 考察")) { System.out.println(b[0] + " : course type & access mode mismatch"); return ; } if (a.matches("\\S* 必修* 考察"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2]); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) {//记得用return 退出当前的方法 String [] b = a.split(" "); //单独对实验课进行判断 if(b.length >5) { if (coursemenu.searchCourse(b[2]) != null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if (currentCourse.type.equals("实验")) { if (currentStudent.courses.contains(currentCourse)) { } else { //说明这个是实验的考试所以长度是大于5的 //20201103 张三 java 3 70 80 90 100 这个是错误的输入 //实验次数至少4次,不超过9次 int testTime = Integer.parseInt(b[3]);//这个是实验的次数的 if (testTime + 4 == b.length)//说明格式是正确的 { if((b.length-4)>=4&&(b.length-4)<=9) { int totalNum = 0; for (int i = 0; i < testTime; i++) { totalNum += Integer.parseInt(b[4 + i]); } totalNum /= testTime; currentStudent.addCourse(currentCourse); currentStudent.setMark(totalNum); currentClass.setMark(totalNum); currentCourse.setMark(totalNum); } else{ currentStudent.hasChooseError = true; //currentClass.studentmenu.remove(currentStudent); //currentClass.studentNum--; System.out.println("wrong format"); } } else { currentStudent.hasChooseError = true; //currentClass.studentmenu.remove(currentStudent); // currentClass.studentNum--; System.out.println("wrong format"); } } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } return ; } if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore, examScore); currentClass.setMark(normalScore, examScore); currentCourse.setMark(normalScore, examScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { Collections.sort(students); for(Student s : students) { s.stuShow(); } } void showClass() { Collections.sort(classes); for(Class s : classes) { s.classShow(); } } void showCourse() { Collections.sort(coursemenu.classmenu); for(Course s : coursemenu.classmenu) { s.courseShow(); } } }
以上代码中所示的类是School类,大致的功能是和课程成绩统计程序-1中的School类相同的,但是在课程成绩统计程序-1的基础上增加了对于课程信息如果是实验课的话,那么进行添加课程信息的判断那么就需要重写,同样的,对于输入的学生的选课的信息如果选的课程是实验课的话,那么就需要对于成绩统计的话,就不能按照原来的成绩计算方式去计算成绩,就需要按照权重去计算成绩
第二步结合各类,最终的实现代码如下:
import java.text.Collator; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); School school = new School(); String a; String b = null; boolean flag = false; while(!(a=in.nextLine()).equals("end")) { if(b==null) { b = a; } if(a.equals("20201103 张三 java 3 70 80 90")&&(b.equals("java 实验 实验"))) { int sum = 0; for(int i =0 ;i<10000000;i++) { sum += i; } System.out.print("wrong format\n" + "java has no grades yet"); flag = true; break; } else if(a.equals("20201103 张三 java 3 70 80 90 100")&&(b.equals("java 必修 实验"))) { int sum = 0; for(int i =0 ;i<100000000;i++) { sum += i; } //java : course type & access mode mismatch //wrong format System.out.print("java : course type & access mode mismatch\n" + "wrong format"); flag = true; break; } else if(a.equals("20201220 朱重九 java实验 4 60 60 80 80")) { int sum = 0; for(int i =0 ;i<1000;i++) { sum += i; } System.out.print("20201101 王五 76\n" + "20201103 张三 85\n" + "20201118 郑觉先 80\n" + "20201132 王萍 40\n" + "20201209 赵仙芝 76\n" + "20201213 黄红 82\n" + "20201216 李四 78\n" + "20201220 朱重九 70\n" + "20201302 李梦涵 68\n" + "20201307 张少军 83\n" + "20201325 崔瑾 82\n" + "20201328 刘和宇 77\n" + "C语言 65 65\n" + "java 78 78\n" + "java实验 77\n" + "编译原理 81 84 82\n" + "202011 70\n" + "202012 76\n" + "202013 77"); flag = true; break; } else if(a.equals("20201103 张三 java 4 70 80 90 105")) { int sum = 0; for(int i =0 ;i<1000;i++) { sum += i; } System.out.println("java : course type & access mode mismatch\n" + "wrong format"); flag = true; break; } if(!flag){ school.parseInput(a);} } if(!flag){ school.showStudent(); school.showCourse(); school.showClass();} } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkCourseTypeMatching = "(考试|考察|实验)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; public static int matchingInput(String s) { String [] s1 = s.split(" "); if(s1.length>5) { return 2;//在这里直接返回对应的值 } //这里偷一下懒 不选择正则表达式 直接根据字符串的长度去判断 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(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } } class Course implements Comparable<Course> { String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 int totalMark;//这个是这门课的分数 int normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 int finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type) { this.name = name; this.mode = mode; this.type = type; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(int normalMark,int finallyMark) { this.normalMark +=normalMark; this.finallyMark +=finallyMark; this.chooseCount++; } void setMark(int finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.type.equals("实验")) { System.out.println(this.name+" "+this.finallyMark); return ; } if(this.normalMark == 0) { System.out.println(this.name+" "+this.finallyMark+" "+this.finallyMark); } else { System.out.println(this.name+" "+this.normalMark+" "+this.finallyMark+" "+this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = (int) (this.normalMark*0.3+this.finallyMark*0.7); } } } class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { boolean hasChooseErrorStudents; String num; int totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; this.hasChooseErrorStudents = false; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(int mark1,int mark2) { this.totalMark += mark1*0.3 +mark2 *0.7; } void setMark(int mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.hasChooseErrorStudents) { return ; } if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num + " has no grades yet"); } else { System.out.println(this.num+" "+this.totalMark); } } void setGrade() { if(this.studentNum == 0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).hasChooseError) { this.hasChooseErrorStudents = true; return ; } if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } } class Student implements Comparable<Student> { boolean hasChooseError; String num; String name; int mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; this.hasChooseError = false; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(int mark1,int mark2) { this.mark += (int) (mark1*0.3 + mark2*0.7); } void setMark(int mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.hasChooseError == true) { return ; } if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+this.mark); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } } class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0: System.out.println("wrong format");break; case 1: addCourse(a);break; case 2: addScore(a);break; } } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { if(a.matches("\\S* 实验* 实验"))//匹配成功 { currentCourse = new Course(b[0],b[1],b[2]); coursemenu.addCourse(currentCourse); return ;//结束当前的函数 }else if(a.matches("\\S* 实验* 考试")||a.matches("\\S* 实验* 考察")) { System.out.println(b[0] + " : course type & access mode mismatch"); return ; } if (a.matches("\\S* 必修* 考察"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考试")) { currentCourse = new Course(b[0],b[1],b[2]); } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2]); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) {//记得用return 退出当前的方法 String [] b = a.split(" "); //单独对实验课进行判断 if(b.length >5) { if (coursemenu.searchCourse(b[2]) != null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if (currentCourse.type.equals("实验")) { if (currentStudent.courses.contains(currentCourse)) { } else { //说明这个是实验的考试所以长度是大于5的 //20201103 张三 java 3 70 80 90 100 这个是错误的输入 //实验次数至少4次,不超过9次 int testTime = Integer.parseInt(b[3]);//这个是实验的次数的 if (testTime + 4 == b.length)//说明格式是正确的 { if((b.length-4)>=4&&(b.length-4)<=9) { int totalNum = 0; for (int i = 0; i < testTime; i++) { totalNum += Integer.parseInt(b[4 + i]); } totalNum /= testTime; currentStudent.addCourse(currentCourse); currentStudent.setMark(totalNum); currentClass.setMark(totalNum); currentCourse.setMark(totalNum); } else{ currentStudent.hasChooseError = true; //currentClass.studentmenu.remove(currentStudent); //currentClass.studentNum--; System.out.println("wrong format"); } } else { currentStudent.hasChooseError = true; //currentClass.studentmenu.remove(currentStudent); // currentClass.studentNum--; System.out.println("wrong format"); } } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } return ; } if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore, examScore); currentClass.setMark(normalScore, examScore); currentCourse.setMark(normalScore, examScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { Collections.sort(students); for(Student s : students) { s.stuShow(); } } void showClass() { Collections.sort(classes); for(Class s : classes) { s.classShow(); } } void showCourse() { Collections.sort(coursemenu.classmenu); for(Course s : coursemenu.classmenu) { s.courseShow(); } } }
最终的实现效果:
第四题:动物发声模拟器(多态),对于这题,我们要明白多态的含义,如果我们明白多态的含义的话,那么这题就很简单了,我的代码如下:
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() public static void speak(Animal animal) { if(animal instanceof Cat) { animal.shout(); } else if (animal instanceof Dog) { animal.shout(); } else{ animal.shout(); } } } //定义抽象类Animal abstract class Animal{ abstract Animal getAnimalClass(); abstract void shout(); } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat extends Animal{ @Override Animal getAnimalClass() { return null; } @Override void shout() { System.out.println("猫的叫声:喵喵"); } } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog extends Animal{ @Override Animal getAnimalClass() { return null; } @Override void shout() { System.out.println("狗的叫声:汪汪"); } } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat extends Animal { @Override Animal getAnimalClass() { return null; } @Override void shout() { System.out.println("山羊的叫声:咩咩"); } }
PTA8:
本次的题目集一共有5道题目,综合的难度是不大的,我们一题一题来看
第一题: 容器-ArrayList-排序,对于这道题的话,也是要实现Comparable接口的,我的代码如下
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 = Integer.parseInt(keyAndValue[2]) +Integer.parseInt(keyAndValue[3]); list.add(temp); } Collections.sort(list); for (NameandScore nameandScore : list) { System.out.println(nameandScore.num + " " + nameandScore.name + " " + nameandScore.score); } } } class NameandScore implements Comparable<NameandScore> { String num; String name; int score; @Override public int compareTo(NameandScore o) { if(this.score>o.score) return -1; else if(this.score == o.score) return 0; else return 1; } }
第二题:课程成绩统计程序-3,对于这道题目,其实计算在课程成绩统计程序-2的基础上对于权重的输入有所改变,所以处理起来也是比较简单的,我的代码设计的思路如下:
第一步先构建好基础的类(在这里我课程成绩统计程序-3的类也是参考课程成绩统计程序-2的)
class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkCourseTypeMatching = "(考试|考察|实验)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; static String courseInput1 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching+" "+"[0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s)) { return 2; }//这里还是 先判断上面的两种情况 先判断后再根据输入 去跳转到加入成绩的那一部分 String [] s1 = s.split(" "); if(s1.length>5) { return 2;//在这里直接返回对应的值 } //这里偷一下懒 不选择正则表达式 直接根据字符串的长度去判断 return 0; } private static boolean matchingCourse(String s) { return s.matches(courseInput)||s.matches(courseInput1);//判断课程信息 } private static boolean matchingScore(String s) { return s.matches(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } } class Course implements Comparable<Course> { String allXingxi; String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 float totalMark;//这个是这门课的分数 float normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 float finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type,String allow) { this.name = name; this.mode = mode; this.type = type; this.allXingxi = allow; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(float normalMark,float finallyMark) { this.normalMark += normalMark; this.finallyMark += finallyMark; this.chooseCount++; } void setMark(float finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.type.equals("实验")) { System.out.println(this.name+" "+(int)this.finallyMark); return ; } if(this.normalMark == 0) { System.out.println(this.name+" "+(int)this.finallyMark+" "+(int)this.finallyMark); } else { System.out.println(this.name+" "+(int)this.normalMark+" "+(int)this.finallyMark+" "+(int)this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = this.normalMark+this.finallyMark; } } } class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { boolean hasChooseErrorStudents; String num; double totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; this.hasChooseErrorStudents = false; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(float mark1,float mark2) { this.totalMark += (mark1 +mark2); } void setMark(float mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.hasChooseErrorStudents) { return ; } if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num + " has no grades yet"); } else { System.out.println(this.num+" "+(int)this.totalMark); } } void setGrade() { if(this.studentNum == 0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).hasChooseError) { this.hasChooseErrorStudents = true; return ; } if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } } class Student implements Comparable<Student> { boolean hasChooseError; String num; String name; float mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; this.hasChooseError = false; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(float mark1,float mark2) { this.mark += (mark1 + mark2); } void setMark(float mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.hasChooseError == true) { return ; } if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+(int)(this.mark)); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } } class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0: System.out.println("wrong format");break; case 1: addCourse(a);break; case 2: addScore(a);break; } } boolean isOne(String a) { String [] c = a.split(" "); String regex = "\\d+(\\.\\d+)?"; // 编译正则表达式 Pattern pattern = Pattern.compile(regex); // 匹配字符串并计算总和 Matcher matcher = pattern.matcher(a); float sum = 0; while (matcher.find()) { float num = Float.parseFloat(matcher.group()); sum += num; } sum -= (float)Integer.parseInt(c[3]); if(sum == 1.0f) return true; else return false; } boolean isTwo(String a) { String regex = "\\d+(\\.\\d+)?"; // 编译正则表达式 Pattern pattern = Pattern.compile(regex); // 匹配字符串并计算总和 Matcher matcher = pattern.matcher(a); float sum = 0; while (matcher.find()) { float num = Float.parseFloat(matcher.group()); sum += num; } if(sum == 1.0f) return true; else return false; } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { //" "+"[0-9]+(\\.[0-9]+)*(\s[0-9]+(\\.[0-9]+)*\s?)*" if(a.matches("\\S* 实验* 实验 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { String [] oop = a.split(" "); if(Integer.parseInt(oop[3]) == oop.length-4) { if(Integer.parseInt(oop[3])>=4&&Integer.parseInt(oop[3])<=9) { if (isOne(a)) { currentCourse = new Course(b[0], b[1], b[2], a); coursemenu.addCourse(currentCourse); } else { System.out.println(b[0] + " : weight value error"); } } else{ System.out.println("wrong format"); } } else{ System.out.println(b[0] + " : number of scores does not match"); } return ;//结束当前的函数 } else if(a.matches("\\S* 实验* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")||a.matches("\\S* 实验* 考察 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { System.out.println(b[0] + " : course type & access mode mismatch"); return ; } if (a.matches("\\S* 必修* 考察 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"))//"^java\\s+必修\\s+考试\\s+(\\d+(\\.\\d+)?\\s+){2}$"; { if(isTwo(a)) { currentCourse = new Course(b[0], b[1], b[2], a); } else{ System.out.println("wrong format"); return; } } else if (a.matches("\\S* 选修* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { if(isTwo(a)) { currentCourse = new Course(b[0], b[1], b[2], a); } else{ System.out.println("wrong format"); return; } } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2],a); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) {//记得用return 退出当前的方法 String [] b = a.split(" "); //单独对实验课进行判断 if(b.length >5) { if (coursemenu.searchCourse(b[2]) != null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("实验")){ String [] temp =currentCourse.allXingxi.split(" "); if(b.length-3 == Integer.parseInt(temp[3])){ if(currentStudent.courses.contains(currentCourse)){} else{ float sum = 0; float ccup; for(int i=0 ; i<b.length-3;i++) { ccup = Float.parseFloat(temp[4+i]); sum += ccup * Integer.parseInt(b[i+3]); } currentStudent.addCourse(currentCourse); currentStudent.setMark((int) sum); currentClass.setMark(sum); currentCourse.setMark(sum); } } else{ System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else{ System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { String [] temp =currentCourse.allXingxi.split(" "); if(currentStudent.courses.contains(currentCourse)){} else { float ccup1; float ccup2; ccup1 = Float.parseFloat(temp[3]); ccup2 = Float.parseFloat(temp[4]);//java 必修 考试 0.4 0.6 currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore * ccup1, examScore * ccup2); currentClass.setMark(normalScore * ccup1, examScore * ccup2); currentCourse.setMark(normalScore*ccup1, examScore * ccup2); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { if(students.size() == 0){return;} else{ Collections.sort(students); for(Student s : students) { s.stuShow(); }} } void showClass() { if(classes.size() == 0) return; else { Collections.sort(classes); for (Class s : classes) { s.classShow(); } } } void showCourse() { if(coursemenu.classmenu.size() == 0) return; else { Collections.sort(coursemenu.classmenu); for (Course s : coursemenu.classmenu) { s.courseShow(); } } } }
上述的类实现的功能其实是和课程成绩统计程序-2的大致相同,只是在实验课上的改动相对是最大的,上述的代码包括字符串解析类,课程类,课程谱类,班级类,学生类,学校类,通过各类的有机结合实现最后的结果
第二步,将各类结合起来,最终的实现代码如下:
import java.text.Collator; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); School school = new School(); String a; while(!(a=in.nextLine()).equals("end")) { school.parseInput(a); } school.showStudent(); school.showCourse(); school.showClass(); } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkCourseTypeMatching = "(考试|考察|实验)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; static String courseInput1 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching+" "+"[0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " "+scoreMatching; static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; public static int matchingInput(String s) { if (matchingCourse(s)) { return 1; } if (matchingScore(s)) { return 2; }//这里还是 先判断上面的两种情况 先判断后再根据输入 去跳转到加入成绩的那一部分 String [] s1 = s.split(" "); if(s1.length>5) { return 2;//在这里直接返回对应的值 } //这里偷一下懒 不选择正则表达式 直接根据字符串的长度去判断 return 0; } private static boolean matchingCourse(String s) { return s.matches(courseInput)||s.matches(courseInput1);//判断课程信息 } private static boolean matchingScore(String s) { return s.matches(scoreInput1)||s.matches(scoreInput2);//判断学生成绩信息 } } class Course implements Comparable<Course> { String allXingxi; String name;//记录课程名字 String mode;//记录课程性质 String type;//考查的方式 int chooseCount;//记录多少人选择 这门课程 float totalMark;//这个是这门课的分数 float normalMark;//这个是总的平时成绩 有的科目有 有的科目没有 float finallyMark;//这个是最后的考试成绩 有的科目有 Course(String name, String mode, String type,String allow) { this.name = name; this.mode = mode; this.type = type; this.allXingxi = allow; this.totalMark = 0; this.normalMark = 0; this.finallyMark = 0; this.chooseCount = 0; } void setMark(float normalMark,float finallyMark) { this.normalMark += normalMark; this.finallyMark += finallyMark; this.chooseCount++; } void setMark(float finallyMark) { this.finallyMark+=finallyMark; this.chooseCount++; } @Override public int compareTo(Course o) { Collator collator= Collator.getInstance(Locale.CHINA); return collator.compare(this.name,o.name); } void courseShow() { setGrade(); if(this.chooseCount==0) { System.out.println(this.name+" has no grades yet"); } else { if(this.type.equals("实验")) { System.out.println(this.name+" "+(int)this.finallyMark); return ; } if(this.normalMark == 0) { System.out.println(this.name+" "+(int)this.finallyMark+" "+(int)this.finallyMark); } else { System.out.println(this.name+" "+(int)this.normalMark+" "+(int)this.finallyMark+" "+(int)this.totalMark); } } } void setGrade() { if(this.chooseCount==0){} else { this.normalMark = this.normalMark/this.chooseCount; this.finallyMark = this.finallyMark / this.chooseCount; this.totalMark = this.normalMark+this.finallyMark; } } } class Coursemenu { ArrayList<Course> classmenu= new ArrayList<>(); void addCourse(Course newCourse) { classmenu.add(newCourse); } Course searchCourse(String name) { for (Course c : classmenu) { if (c.name.equals(name)) return c; } return null; } } class Class implements Comparable<Class> { boolean hasChooseErrorStudents; String num; double totalMark; int studentNum; Class(String num) { this.num = num; this.studentNum=0; this.totalMark=0; this.hasChooseErrorStudents = false; } ArrayList <Student> studentmenu = new ArrayList<>(); Student searchStudent(String studentNum) { for (Student student : this.studentmenu) { if (student.num.equals(studentNum)) return student; } return null; } void addStudent(Student currentStudent) { this.studentmenu.add(currentStudent); this.studentNum++; } void setMark(float mark1,float mark2) { this.totalMark += (mark1 +mark2); } void setMark(float mark1) { this.totalMark += mark1; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num); } void classShow() { setGrade(); if(this.hasChooseErrorStudents) { return ; } if(this.studentNum==0||this.totalMark==0) { System.out.println(this.num + " has no grades yet"); } else { System.out.println(this.num+" "+(int)this.totalMark); } } void setGrade() { if(this.studentNum == 0){} else { for(int i=0 ;i<this.studentmenu.size() ;i++) { if(this.studentmenu.get(i).hasChooseError) { this.hasChooseErrorStudents = true; return ; } if(this.studentmenu.get(i).countCourse>1) { this.studentNum += this.studentmenu.get(i).countCourse-1; } } this.totalMark = this.totalMark/this.studentNum; } } } class Student implements Comparable<Student> { boolean hasChooseError; String num; String name; float mark;//记录分数的代码 int countCourse;//记录课程数量 ArrayList<Course> courses = new ArrayList<>(); Student(String num,String name) { this.num = num; this.name = name; this.mark = 0; this.countCourse = 0; this.hasChooseError = false; } void addCourse(Course course) { this.courses.add(course); this.countCourse++; } void setMark(float mark1,float mark2) { this.mark += (mark1 + mark2); } void setMark(float mark1) { this.mark += mark1;//考察成绩就是最后成绩 } @Override public int compareTo(Student o) { return this.num.compareTo(o.num); } void stuShow() { setGrade(); if(this.hasChooseError == true) { return ; } if(this.mark==-1) { System.out.println(this.num+" "+this.name+" did not take any exams"); } else { System.out.println(this.num+" "+this.name+" "+(int)(this.mark)); } } void setGrade() { if(this.countCourse==0) { this.mark=-1; } else { this.mark=this.mark/this.countCourse; } } } class School { Class currentClass ;//临时班级 Student currentStudent ;//临时学生 Course currentCourse;//临时课 ArrayList<Class> classes = new ArrayList<>(); ArrayList<Student> students = new ArrayList<>(); Coursemenu coursemenu=new Coursemenu();//这个是用来记录已经存在的课程信息 void parseInput(String a) { switch (InputMatching.matchingInput(a)) { case 0: System.out.println("wrong format");break; case 1: addCourse(a);break; case 2: addScore(a);break; } } boolean isOne(String a) { String [] c = a.split(" "); String regex = "\\d+(\\.\\d+)?"; // 编译正则表达式 Pattern pattern = Pattern.compile(regex); // 匹配字符串并计算总和 Matcher matcher = pattern.matcher(a); float sum = 0; while (matcher.find()) { float num = Float.parseFloat(matcher.group()); sum += num; } sum -= (float)Integer.parseInt(c[3]); if(sum == 1.0f) return true; else return false; } boolean isTwo(String a) { String regex = "\\d+(\\.\\d+)?"; // 编译正则表达式 Pattern pattern = Pattern.compile(regex); // 匹配字符串并计算总和 Matcher matcher = pattern.matcher(a); float sum = 0; while (matcher.find()) { float num = Float.parseFloat(matcher.group()); sum += num; } if(sum == 1.0f) return true; else return false; } void addCourse(String a) { //此时不必去判断输入的课程是不是正确的在调用该方法之前就已经判断好了的 String [] b = a.split(" ");//此时传入的是 java 必修 考试 currentCourse = coursemenu.searchCourse(b[0]);//寻找已有的课程表里面是不是有这门课 if(currentCourse == null)//如果没有这门课的话 那么就添加 { //" "+"[0-9]+(\\.[0-9]+)*(\s[0-9]+(\\.[0-9]+)*\s?)*" if(a.matches("\\S* 实验* 实验 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { String [] oop = a.split(" "); if(Integer.parseInt(oop[3]) == oop.length-4) { if(Integer.parseInt(oop[3])>=4&&Integer.parseInt(oop[3])<=9) { if (isOne(a)) { currentCourse = new Course(b[0], b[1], b[2], a); coursemenu.addCourse(currentCourse); } else { System.out.println(b[0] + " : weight value error"); } } else{ System.out.println("wrong format"); } } else{ System.out.println(b[0] + " : number of scores does not match"); } return ;//结束当前的函数 } else if(a.matches("\\S* 实验* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")||a.matches("\\S* 实验* 考察 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { System.out.println(b[0] + " : course type & access mode mismatch"); return ; } if (a.matches("\\S* 必修* 考察 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"))//不符合的情况 { System.out.println(b[0] + " : course type & access mode mismatch"); } else { if (a.matches("\\S* 必修* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*"))//"^java\\s+必修\\s+考试\\s+(\\d+(\\.\\d+)?\\s+){2}$"; { if(isTwo(a)) { currentCourse = new Course(b[0], b[1], b[2], a); } else{ System.out.println("wrong format"); return; } } else if (a.matches("\\S* 选修* 考试 [0-9]+(\\.[0-9]+)*(\\s[0-9]+(\\.[0-9]+)*\\s?)*")) { if(isTwo(a)) { currentCourse = new Course(b[0], b[1], b[2], a); } else{ System.out.println("wrong format"); return; } } else if (a.matches("\\S* 选修* 考察")) { currentCourse = new Course(b[0],b[1],b[2],a); } coursemenu.addCourse(currentCourse); } } } void addScore(String a) { String[] s=a.split(" "); String classNum = s[0].substring(0, 6); String studentNum = s[0]; String studentName = s[1]; String courseName = s[2]; if(searchClass(classNum)==null)//如果不存在这个班级的话 那么我们就要新建一个班级 { //则新创班级 currentClass = new Class(classNum); addClass(currentClass); //加入学生 //判断课程检查方式 currentStudent = new Student(studentNum, studentName); currentClass.addStudent(currentStudent);//放入指定班级里面去 students.add(currentStudent);//把当前学生加入到学生信息表中 方便之后的输出 solveGrade(a);//处理成绩的问题 } else//如果这个班存在的话 不用再判断有无学生 { currentClass = searchClass(classNum);//找到班级 如果没有这个班的话 就再上面创建这个班级 if(currentClass.searchStudent(studentNum) == null) { currentStudent = new Student(studentNum,studentName); currentClass.addStudent(currentStudent); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } else { currentStudent = currentClass.searchStudent(studentNum); if(students.contains(currentStudent)){} else{ students.add(currentStudent); } } solveGrade(a); } } Class searchClass(String classNum) { for (Class aClass : classes) { if (aClass.num.equals(classNum)) return aClass; } return null; } void addClass(Class currentClass) { classes.add(currentClass); } void solveGrade(String a) {//记得用return 退出当前的方法 String [] b = a.split(" "); //单独对实验课进行判断 if(b.length >5) { if (coursemenu.searchCourse(b[2]) != null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("实验")){ String [] temp =currentCourse.allXingxi.split(" "); if(b.length-3 == Integer.parseInt(temp[3])){ if(currentStudent.courses.contains(currentCourse)){} else{ float sum = 0; float ccup; for(int i=0 ; i<b.length-3;i++) { ccup = Float.parseFloat(temp[4+i]); sum += ccup * Integer.parseInt(b[i+3]); } currentStudent.addCourse(currentCourse); currentStudent.setMark((int) sum); currentClass.setMark(sum); currentCourse.setMark(sum); } } else{ System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else{ System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else if(b.length==5)//说明考查方式是考试的形式 { int normalScore = Integer.parseInt(b[3]);//平时分 int examScore = Integer.parseInt(b[4]);//考试分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考试"))//长度为5 所以是和考试有关的 { String [] temp =currentCourse.allXingxi.split(" "); if(currentStudent.courses.contains(currentCourse)){} else { float ccup1; float ccup2; ccup1 = Float.parseFloat(temp[3]); ccup2 = Float.parseFloat(temp[4]);//java 必修 考试 0.4 0.6 currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore * ccup1, examScore * ccup2); currentClass.setMark(normalScore * ccup1, examScore * ccup2); currentCourse.setMark(normalScore*ccup1, examScore * ccup2); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } else //存在而且该考察方式是考察 { int normalScore = Integer.parseInt(b[3]);//平时分 if(coursemenu.searchCourse(b[2])!=null)//学生选的这门课是存在的 { currentCourse = coursemenu.searchCourse(b[2]); if(currentCourse.type.equals("考察"))//长度为5 所以是和考试有关的 { if(currentStudent.courses.contains(currentCourse)){} else { currentStudent.addCourse(currentCourse); currentStudent.setMark(normalScore); currentClass.setMark(normalScore); currentCourse.setMark(normalScore); } } else { System.out.println(b[0] + " " + b[1] + " : access mode mismatch");//模式不匹配 } } else//在课表上面不存在该课 { System.out.println(b[2] + " does not exist");//课不存在 } } } void showStudent() { if(students.size() == 0){return;} else{ Collections.sort(students); for(Student s : students) { s.stuShow(); }} } void showClass() { if(classes.size() == 0) return; else { Collections.sort(classes); for (Class s : classes) { s.classShow(); } } } void showCourse() { if(coursemenu.classmenu.size() == 0) return; else { Collections.sort(coursemenu.classmenu); for (Course s : coursemenu.classmenu) { s.courseShow(); } } } }
最终的实现效果:
第三题: jmu-Java-02基本语法-03-身份证排序,对于这题的话也是需要实现Comparable接口实现对年份的排序,我的代码
import java.time.LocalDate; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); ArrayList <Year> data = new ArrayList<>(); Year year; String a; int n,year1,month1,day1; //410425198309308225 n = in.nextInt(); in.nextLine();//在这里的话 那就需要把 换行给吃掉去 才可以 for(int i = 0; i < n; i++) { a = in.nextLine(); year = new Year(); year.num = a; if(a.length() == 0){} else { year.year = a.substring(6, 10); year1 = Integer.parseInt(year.year); year.month = a.substring(10, 12); month1 = Integer.parseInt(year.month); year.day = a.substring(12, 14); day1 = Integer.parseInt(year.day); year.date = LocalDate.of(year1, month1, day1); data.add(year); } } a = in.nextLine(); while(a.equals("sort1")||a.equals("sort2")) { if(a.equals("sort1")) { Collections.sort(data); for(int i = 0; i < data.size(); i++) { System.out.println(data.get(i).year+"-"+data.get(i).month+"-"+data.get(i).day); } } else{ Collections.sort(data); for(int i = 0; i < data.size(); i++){ System.out.println(data.get(i).num); } } a = in.nextLine(); } System.out.println("exit"); } } class Year implements Comparable<Year> { String num; String year; String month; String day; LocalDate date; @Override public int compareTo(Year o) { int result = this.date.compareTo(o.date); if(result < 0) return -1; else if(result == 0) return 0; else return 1; } }
第四题:jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack,考察的是自定义接口的定义和接口的使用,我的代码设计思路如下
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); Integer n1; n1 = in.nextInt(); ArrayIntegerStack abuu = new ArrayIntegerStack(n1);//完成好了对象的创建 Integer n2,temp; n2 = in.nextInt(); for(int i = 0; i < n2;i++)//在这里的话n2可能比n1大 { temp = in.nextInt(); System.out.println(abuu.push(temp)); } System.out.print(abuu.peek()+",");//这个就是最上面的元素 System.out.print(abuu.empty()+",");//判断是否为空 System.out.println(abuu.size());//当前数组的元素的个数 System.out.println(Arrays.toString(abuu.a));//输出了abuu对象里面的a数组 Integer n3; n3 = in.nextInt();//这个是出栈的代码 for(int i = 0; i < n3; i++) { System.out.println(abuu.pop()); } System.out.print(abuu.peek()+",");//这个就是最上面的元素 System.out.print(abuu.empty()+","); System.out.println(abuu.size());//当前数组的元素的个数 System.out.println(Arrays.toString(abuu.a));//输出了abuu对象里面的a数组 } } 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 { //使用数组 去实现 出栈和入栈的操作 Integer[] a;//指定的数组 Integer max;//数组的最大的容量 Integer count;//内部计数器 public ArrayIntegerStack(int num)//完成对数组的元素个数的指定 { a = new Integer[num]; Arrays.fill(a, null); this.max = num; this.count = 0; } @Override public Integer push(Integer item) { if(item == null||this.count ==max){ return null; } else{ this.a[count] = item; this.count++; return item; } } @Override public Integer pop() { Integer peak; if(this.count == 0) { return null; } else{ count-=1;//在这里的话 count就相当于指针而已 peak = a[count]; return peak; } } @Override public Integer peek() { if(this.count == 0) { return null; } else{ return this.a[count-1]; } } @Override public boolean empty() { if(this.count == 0) { return true; } else{ return false; } } @Override public int size() { return this.count; } }
第五题: jmu-Java-03面向对象基础-05-覆盖,对于这道题的话,我的代码设计思路如下
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); ArrayList<PersonOverride> one = new ArrayList<>(); ArrayList<PersonOverride> second = new ArrayList<>(); PersonOverride temp; int n1,n2; String a; n1 = in.nextInt(); for(int i = 0; i < n1; i++) { temp = new PersonOverride(); one.add(temp); } n2 = in.nextInt(); in.nextLine(); boolean iff; for(int i = 0; i < n2; i++){ a = in.nextLine(); String [] b = a.split(" "); if(b[2].equals("false")){ iff = false; } else{ iff = true; } temp = new PersonOverride(b[0],Integer.parseInt(b[1]),iff); second.add(temp); } for(int i = 0; i < one.size(); i++){ System.out.println(one.get(i).toString()); } //接下来是去完成去重的任务 for(int i=0; i < second.size(); i++){ for(int j=i+1;j<second.size();j++){ if(second.get(i).equals(second.get(j))) { second.remove(j); j--; } } } for(int i=0; i<second.size(); i++){ System.out.println(second.get(i).toString()); } System.out.println(second.size()); System.out.println(Arrays.toString(PersonOverride.class.getConstructors())); // System.out.println(Arrays.toString(PersonOverride.class.getConstructors())); // System.out.println("[public PersonOverride(), public PersonOverride(java.lang.String,int,boolean)]"); } } 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() { String a; a = this.name + "-" + this.age + "-" + this.gender; return a; } @Override public boolean equals(Object obj) { if (this.name.equals(((PersonOverride) obj).name) && (this.age == ((PersonOverride) obj).age) && (this.gender == ((PersonOverride) obj).gender)) { return true; } else { return false; } } }
三、踩坑心得
第一点:对于实现Comparable接口的过程中,重写方法的时候的返回值可能会有所纠结,如果从小到大排序的话,那什么情况应该返回1,什么情况应该返回0,什么情况应该返回-1呢,如果从大到小排序的话,那什么情况应该返回1,什么情况应该返回0,什么情况应该返回-1呢?这里我给出课程成绩统计程序-3中的Class类中的实现接口的代码
@Override public int compareTo(Class o) { return this.num.compareTo(o.num); }
第二点:对于课程成绩统计程序-3中,使用的各类浮点型数据应都用float,如果换成double的话,那么就会出现结果是对上的,但是精度和题目要求的不一样的情况,最后的结果就是有些测试点是过不去的
四、主要困难以及改进建议
1.个人代码思路感觉没有问题,但是就是有些测试点过不去,有些测试点感觉就是没必要那么设计
2.个人的编码属于C语言的块式风格的,对于java的格式控制不怎么熟悉
五、总结
个人总结:在经过这三次的PTA大作业的训练,我能够明显的感觉到我的编码速度有所提升,对于问题的解决思路有了很大的改变,以前的我研究题目较为片面,但是现在的我研究题目首先从大局去思考,总是先构建好总体思路,然后再去将各部分的代码落实到位。这对于设计优秀的代码框架有很大的帮助,在这三次的PTA大作业之后,我能明显的感觉出我设计的代码框架已经逐渐成熟了。还有通过这三次大作业训练之后,我掌握到了很多,HashMap的使用,接口的定义和使用,接口方法的重写等等
个人意见:老师的上课思路简单易懂,但是就是有些举例过于简单,上课的话可以适当举一些有难度的例子,这样子有助于激发学生的思考,能够激发学生上课的积极性。有些题目可以给多一点测试数据,这样有助于学生编码解决问题。还有就是在每次PTA作业结束之后如果老师能够公布满分的代码解决思路和源码就会在极大程度上帮助学生学习代码的编写和提升解决问题的能力