前言
本次实验依旧运用了抽象类的知识点,并且结合了正则表达式进行考察;题目难度不算太大,格式识别中种种要求应接不暇,常常是顾此失彼,只要确定好了各种字符串的正则表达式,许多问题都会迎刃而解;
设计与分析
这次把类设计的各个知识点全部回顾了一遍,包括构造方法、方法重写、抽象类、继承、动态联编,这次作业是比较经典的面向对象练习,对OO思维是一种很好的锻炼;
类图:
源码:
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String nextLine = input.nextLine();
ParseInput handle=new ParseInput();
while (!nextLine.equals("end")) {
handle.parseInput(nextLine);//解析用户输入的每一行数据
nextLine = input.nextLine();
}
handle.showStudents();
handle.showCourses();
handle.showClasses();
}
}
class ParseInput{
ArrayList<Course> courseArrayList = new ArrayList<>();
ArrayList<Student> studentArrayList = new ArrayList<>();
ArrayList<Choose> chooseArrayList = new ArrayList<>();
ArrayList<myClass> classArrayList = new ArrayList<>();
public void parseInput(String nextLine) {
String[] arraylist = nextLine.split(" ");
switch (InputMatching.matchingInput(nextLine)){
case 1:
inputCourse(arraylist);
break;
case 2:
inputScore(arraylist);
break;
case 0:
System.out.println("wrong format");
break;
}
}
Course getCourse(String courseName){
for (Course course : courseArrayList) {
if (course.getCsName().equals(courseName))
return course;
}
return null;
}
myClass getClass(String classId){
for (myClass myClass : classArrayList) {
if (myClass.getID().equals(classId))
return myClass;
}
return null;
}
Student getStudent(String stuId){
for (Student student : studentArrayList) {
if (student.getStNumber().equals(stuId))
return student;
}
return null;
}
private void inputScore(String[] a){
myClass myclass;
Student student;
myclass=getClass(a[0].substring(0,6));
if(myclass==null){
myclass=new myClass(a[0].substring(0,6));
classArrayList.add(myclass);
}
student=getStudent(a[0]);
if(student==null){
student=new Student(a[0], a[1]);
studentArrayList.add(student);
myclass.addStudent(student);
}
Course course=getCourse(a[2]);
if(course==null){
System.out.println(a[2]+" does not exist");
return;
}
if(!checkGrade(a,course))
return;
Score score;
if(a.length==4){
score=new kcScore(Integer.parseInt(a[3]));
}else if(a.length==5){
score=new ksScore(Integer.parseInt(a[3]),Integer.parseInt(a[4]));
}else {
ArrayList<Integer> exScores=new ArrayList<>();
for (int i=4;i<a.length;i++)
exScores.add(Integer.parseInt(a[i]));
score=new exScore(exScores,Integer.parseInt(a[3]));
}
if(existChooseCourse(student,course)) return;//重复
Choose chooseCourse = new Choose(course, student, score);
chooseArrayList.add(chooseCourse);
}
public void inputCourse(String[] a){
Course course = new Course(a[0],a[1],a[2]);
if(!checkCourse(course))
return;
if(getCourse(a[0])==null){//没有重复的课程
course=new Course(a[0], a[1], a[2]);
courseArrayList.add(course);
}
}
boolean checkCourse(Course course){
if(course.getCsCharacter().equals("必修")&&course.getCsExamine().equals("考试"))
return true;
if(course.getCsCharacter().equals("选修")&&course.getCsExamine().equals("考试"))
return true;
if(course.getCsCharacter().equals("选修")&&course.getCsExamine().equals("考察"))
return true;
if(course.getCsCharacter().equals("实验")&&course.getCsExamine().equals("实验"))
return true;
System.out.println(course.getCsName()+" : course type & access mode mismatch");
return false;
}
boolean existChooseCourse(Student stu,Course course){
for (Choose choose : chooseArrayList) {
if (choose.getCourse().getCsName().equals(course.getCsName())) {
if (choose.getStudent().getStName().equals(stu.getStName()))
return true;
}
}
return false;
}
private boolean checkGrade(String[] items,Course course){
String courseType=course.getCsExamine();
if(courseType.equals("考试")&&items.length==5){
return true;
}
if(courseType.equals("考察")&&items.length==4){
return true;
}
if(courseType.equals("实验")){
if(items.length==Integer.parseInt(items[3])+4)
return true;
}
System.out.println(items[0]+" "+items[1]+" : access mode mismatch");
return false;
}
public static int getAvagScore1(ArrayList<Choose> courseSelects)//平时
{
int sum = 0;
for(Choose cs : courseSelects)
{
sum +=((ksScore)(cs.score)).getUsualScore();
}
return sum/courseSelects.size();
}
public int getAvagScore2(ArrayList<Choose> courseSelects)//期末
{
int sum =0;
for(Choose cs : courseSelects)
{
sum += cs.score.getFinalScore();
}
return sum/courseSelects.size();
}
public int getAvgTotalScore(ArrayList<Choose> listChooseCourse)
{
int sum =0;
for(Choose cs : listChooseCourse)
{
sum +=cs.score.getTotalScore();
}
return sum/listChooseCourse.size();
}
public ArrayList<Choose> getStudentSelects(String stNumber) {
ArrayList<Choose> stus = new ArrayList<>();
for (Choose choose : chooseArrayList) {
if (choose.student.getStNumber().equals(stNumber)) {
stus.add(choose);
}
}
if(stus.size()!=0)
return stus;
else return null;
}
public ArrayList<Choose> getCourseSelects(String courseName){
ArrayList<Choose> courses = new ArrayList<>();
for (Choose choose : chooseArrayList) {
if (choose.course.getCsName().equals(courseName)) {
courses.add(choose);
}
}
if(courses.size()!=0)
return courses;
else return null;
}
public ArrayList<Choose> getClassSelects(String classID){
ArrayList<Choose> classes = new ArrayList<>();
for (Choose choose : chooseArrayList) {
if (choose.student.getStNumber().substring(0, 6).equals(classID)) {
classes.add(choose);
}
}
if(classes.size()!=0)
return classes;
else return null;
}
public void showStudents() {
Collections.sort(studentArrayList);
for (Student student : studentArrayList) {
ArrayList<Choose> stuCourseSelects = getStudentSelects(student.getStNumber());
//从总选课表Choose中获取该生的选课记录集合
if (stuCourseSelects != null) {
System.out.println(student.getStNumber() + " " + student.getStName() + " " + getAvgTotalScore(stuCourseSelects));
} else {
System.out.println(student.getStNumber() + " " + student.getStName() + " " + "did not take any exams");
}
}
}
public void showCourses() {
Collections.sort(courseArrayList);
for (Course course : courseArrayList) {
ArrayList<Choose> CourseSelects = getCourseSelects(course.getCsName());
if (CourseSelects != null) {
if (course.getCsExamine().equals("考试"))
System.out.println(course.getCsName() + " " + getAvagScore1(CourseSelects) + " " + getAvagScore2(CourseSelects) + " " + getAvgTotalScore(CourseSelects));
if (course.getCsExamine().equals("考察"))
System.out.println(course.getCsName() + " " + getAvagScore2(CourseSelects) + " " + getAvgTotalScore(CourseSelects));
if(course.getCsExamine().equals("实验"))
System.out.println(course.getCsName() + " " + getAvgTotalScore(CourseSelects));
} else {
System.out.println(course.getCsName() + " has no grades yet");
}
}
}
public void showClasses() {
Collections.sort(classArrayList);
for (myClass myClass : classArrayList) {
ArrayList<Choose> stuClassSelects = getClassSelects(myClass.getID());
if (stuClassSelects != null) {
System.out.println(myClass.getID() + " " + getAvgTotalScore(stuClassSelects));
} else {
System.out.println(myClass.getID() + " " + "has no grades yet");
}
}
}
}
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 = "(考试|考察|实验)";
static String exCountMatching="[4-9]";
static String exScores="(([1-9]?\\d|100)\\s){3,8}([1-9]?\\d|100)";
//cousrInput用于定义课程信息模式(正则表达式)
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
//scoreInput用于定义成绩信息模式(正则表达式)
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching;
static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching;
static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " "+exCountMatching+" "+exScores;
public static int matchingInput(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore(s)) {
return 2;
}
return 0;
}
private static boolean matchingCourse(String s) {
return s.matches(courseInput);
}
private static boolean matchingScore(String s) {
return (s.matches(scoreInput) || s.matches(scoreInput1)||s.matches(scoreInput2));
}
}
class Course implements Comparable<Course>{
private String csName;
private String csCharacter;
private String csExamine;
public Course(String csName, String csCharacter, String csExamine) {
this.csName = csName;
this.csCharacter = csCharacter;
this.csExamine = csExamine;
}
public String getCsName() {
return csName;
}
public String getCsCharacter() {
return csCharacter;
}
public String getCsExamine() {
return csExamine;
}
@Override
public int compareTo(Course o) {
Comparator<Object> compare = Collator.getInstance(Locale.CHINA);
return compare.compare(csName,o.getCsName());
}
}
class ksScore extends Score{//考试
private int Score1;//平时
public int getUsualScore() {
return Score1;
}
public ksScore(int usualScore, int finalScore){
super(finalScore);
this.Score1=usualScore;
this.totalScore=(int)(finalScore*0.7+usualScore*0.3);
}
}
class exScore extends Score{
ArrayList<Integer> exScores=new ArrayList<>();
public exScore(ArrayList<Integer> exScores,int finalScore){
super(finalScore);
this.exScores=exScores;
int sum=0;
for (Integer exScore : this.exScores) {
sum+=exScore;
}
finalScore=sum/exScores.size();
this.totalScore=finalScore;
}
}
class kcScore extends Score{//考察
public kcScore(int finalScore){
super(finalScore);
this.totalScore=finalScore;
}
}
class Student implements Comparable<Student>{
private String stuNumber;
private myClass myclass;
private String stuName;
public Student(String stuNumber, String stuName) {
this.stuName=stuName;
this.stuNumber=stuNumber;
}
public String getStNumber() {
return stuNumber;
}
public String getStName() {
return stuName;
}
@Override
public int compareTo(Student student){
return getStNumber().compareTo(student.getStNumber());
}
}
class Choose {
Course course;
Student student;
Score score;
public Course getCourse() {
return course;
}
public Student getStudent() {
return student;
}
public Choose(Course course, Student student, Score score) {
this.course = course;
this.student = student;
this.score = score;
}
}
class myClass implements Comparable<myClass>{
private String ID;
ArrayList<Student> listStudent=new ArrayList<>();
void addStudent(Student stu){
listStudent.add(stu);
}
public myClass(String ID) {
this.ID = ID;
}
public String getID() {
return ID;
}
@Override
public int compareTo(myClass myclass){
return ID.compareTo(myclass.getID());
}
}
class Score{
protected int Score2;//期末
protected int totalScore;
public int getTotalScore() {
return totalScore;
}
public int getFinalScore() {
return Score2;
}
public Score(int finalScore) {
this.Score2=finalScore;
}
}
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 = "(考试|考察|实验)";
static String exCountMatching="[4-9]";
static String exScores="(([1-9]?\\d|100)\\s){3,8}([1-9]?\\d|100)";
该部分解决了输入格式的所有正确形式,使之后代码的编写变得更简单(主要是因为PTA八股文式的考察真的蛋疼);
class Score{
protected int Score2;//期末
protected int totalScore;
public int getTotalScore() {
return totalScore;
}
public int getFinalScore() {
return Score2;
}
public Score(int finalScore) {
this.Score2=finalScore;
}
}
该部分给出成绩的成绩的父类,在计算考试和考察成绩时分别使用继承该类的子类即可;
踩坑心得
最先我尝试过对每个格式采取逐个相等的方法,过程相当麻烦,最后甚至超过了PTA的最大限度,并且在写完代码后,测试点确实是能过,但是格式错误无法从根本上解决,既然给出最大限度并出了题目,就说明有更简洁的方法可以完成相应的工作,在使用正则表达式后代码明显简洁了许多,并且解决了格式错误的问题;
首先我尝试的时在类里创建另外类的链表,在格式正确的情况下添加进链表中,我个人认为还是比较符合面向对象的思想,最后还是有些测试点解决不了,改进了几次,最后方案为,先进行格式判断,正确之后无论对错都添加进链表中,再经过一系列方法的筛选,最后打印出结果;
改进建议
可以将Score改成抽象类,代码量太大了,后续再添加成绩类型时可能会忘记一些方法,改成抽象类可以在编写时,不需要太注意分数的计算方法,在一定程度上帮助编写代码的实用性;
总结
本次作业,我个人进步最大的地方是学习了几个设计模式来辅助自己设计,这让我代码整体结构比较好,思路清晰,逻辑严谨。这次作业我也学到了多线程编程的基本方法;
本次实验中第一次接触了正则表达式,也体会到了正则表达式的强大,正则的效率挺高的,在很多情况下都能用到,对正则表达式更加熟练了;
但是,我还有许多地方有待进步,比如测试环节。设计模式也需要抓紧时间学习。
标签:return,String,int,ArrayList,系统,学生,course,成绩,public From: https://www.cnblogs.com/catfishhome/p/17510231.html