一、前言
第三次在博客园上发布面向对象程序设计(Java)的题目集总结blog。这一系列题目是关于课程成绩统计程序,主要用于计算和输出学生的成绩信息。
- 关于知识点:
三次作业主要是运用Java的基本语法知识,例如:选择、循环、数组、方法等内容,以及组合聚合等各种java关系。语法知识基本与C语言一致,除了一些表达方式不同,还有比如输入输出语句还有初始化数组等一些语句不同,因此写起来也更容易适应。而到了期中考试就是利用不同的关系,来实现想实现的功能。
- 关于题量:
题目数量不断减少,但是难度也在逐渐增加,所以花在写PTA上的时间总的来说还是不少,甚至会增加。部分题目集都需要设计类,对语言模式等结构需要掌握,独立思考,就需要对程序进行设计,不然会很混乱。前期其他课程的作业量也比较多,这种题量较为适中。
- 关于难度:
- 第六·次作业难度分析: 根据题目描述,该课程成绩统计程序需要进行多个步骤的处理和计算,包括输入课程信息、课程成绩信息的解析,计算各种平均分并按规定格式输出。难度较高的地方在于对输入信息的解析和处理,以及对不同情况的判断和错误处理。
- 第七次作业难度分析: 相较于第一次的题目,课程成绩统计程序-2在添加了实验课程,并且实验课程成绩的计算方式与考试和考察不同。因此,该题目的难度相对较高。
- 第八次作业难度分析:相较于前两次的题目,课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,并将成绩类的继承关系改为组合关系。这个变化增加了对分项成绩的处理和权重的管理,使得程序的设计更加灵活和可扩展,但同时也增加了一定的复杂性。
二、设计与分析
7-3 课程成绩统计程序-1
类图:
代码如下:
import java.text.Collator; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; public class Main { public static Scanner scanner = new Scanner(System.in); public static final Map<String, Course> courseMap = new TreeMap<>(); public static final TreeSet<Student> students = new TreeSet<>(); public static final List<StudentScore> scores = new ArrayList<>(); public static final TreeSet<Ban> bans = new TreeSet<>(); public static Student getStudent(Integer id, String name) { for (Student student : students) { if (student.id.equals(id) && student.name.equals(name)) { return student; } } Student student1 = new Student(); student1.name = name; student1.id = id; students.add(student1); return student1; } public static Ban getBan(Integer code) { for (Ban ban : bans) { if (ban.code.equals(code)) { return ban; } } Ban ban = new Ban(); ban.code = code; bans.add(ban); return ban; } public static void main(String[] args) { while (true) { String input = scanner.nextLine(); String[] s = input.split(" "); if (input.matches("(.*?)\\s+(必修|选修)\\s+(考试|考察)$")) { if (s[0].length()>10){ System.out.println("wrong format"); continue; } Course course = new Course(s); if (course.bi&&!course.shi){ System.out.println(course.name+" : course type & access mode mismatch"); continue; } courseMap.put(course.name, course); } else if (input.matches("(\\d+)\\s+(\\S+)\\s+(.*?)\\s*(\\d*)\\s+(\\d+)$")) { if (s.length==5){ Integer pingshi = Integer.valueOf(s[3]); Integer qimo = Integer.valueOf(s[4]); if (pingshi>100||pingshi<0||qimo>100||qimo<0){ System.out.println("wrong format"); continue; } }else if (s.length == 4){ Integer qimo = Integer.valueOf(s[3]); if (qimo>100||qimo<0){ System.out.println("wrong format"); continue; } } if (s[0].length()!=8){ System.out.println("wrong format"); continue; } if (s[1].length()>10){ System.out.println("wrong format"); continue; } if (s[2].length()>10){ System.out.println("wrong format"); continue; } StudentScore sc = new StudentScore(); sc.student = getStudent(Integer.valueOf(s[0]), s[1]); sc.ban = getBan(Integer.valueOf((sc.student.id + "").substring(0,6))); sc.ban.students.add(sc.student); Course course = courseMap.get(s[2]); if (course != null) { sc.course = course; }else { System.out.println(s[2]+" does not exist"); continue; } if (s.length==5){ Integer pingshi = Integer.valueOf(s[3]); Integer qimo = Integer.valueOf(s[4]); if (pingshi>100||pingshi<0||qimo>100||qimo<0){ System.out.println("wrong format"); continue; } if (course.bi){ if (course.shi){ sc.pingshi = Integer.valueOf(s[3]); sc.qimo = Integer.valueOf(s[4]); }else { System.out.println(sc.student.id+" "+sc.student.name+ " : course type & access mode mismatch"); continue; } }else { if (course.shi){ sc.pingshi = Integer.valueOf(s[3]); sc.qimo = Integer.valueOf(s[4]); }else { System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch"); continue; } } }else if (s.length == 4){ Integer qimo = Integer.valueOf(s[3]); if (qimo>100||qimo<0){ System.out.println("wrong format"); continue; } if (course.bi){ if (course.shi){ System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch"); continue; }else { sc.qimo = Integer.valueOf(s[3]); } }else { if (course.shi){ System.out.println(sc.student.id+" "+sc.student.name+ " : access mode mismatch"); continue; }else { sc.qimo = Integer.valueOf(s[3]); } } } scores.add(sc); } else if (input.equals("end")) { break; } } for (Student student : students) { Double all = 0.0; Double count = 0.0; for (StudentScore score : scores) { if (score.student.equals(student)) { student.scores.add(score); if (score.course.bi) { if (score.course.shi) { all += ((float) score.pingshi * 0.3); all += ((float) score.qimo * 0.7); count++; } else { } } else { if (score.course.shi) { all += ((float) score.pingshi * 0.3); all += ((float) score.qimo * 0.7); count++; } else { count++; all += score.qimo; } } } } if (count==0){ System.out.println(student.id+" "+student.name+ " did not take any exams"); } else { int val = (int) Math.floor(all / count); System.out.println(student.id + " " + student.name + " " + val); } } for (Course course : courseMap.values().stream().sorted().collect(Collectors.toList())) { Integer all = 0; Integer allmo = 0; Integer zong = 0; Integer count = 0; for (StudentScore score : scores) { if (score.course.equals(course)) { if (course.shi) { all += score.pingshi; allmo += score.qimo; count++; } else { allmo += score.qimo; count++; } } } if (count == 0) { System.out.println(course.name + " has no grades yet"); } else { zong += all + allmo; Integer pingAll = (int) Math.floor((float) all / count); Integer pingMo = (int) Math.floor((float) allmo / count); if (course.shi) { System.out.println(course.name + " " + pingAll + " " + pingMo + " " + (int) Math.floor(pingAll*0.3+pingMo*0.7)); } else { System.out.println(course.name + " " + pingMo + " " + pingMo); } } } for (Ban ban : bans) { Double all = 0.0; Double count = 0.0; for (Student student : ban.students) { for (StudentScore score : student.scores) { if (score.course.bi) { if (score.course.shi) { all += (int) ((float) score.pingshi * 0.3); all += (int) ((float) score.qimo * 0.7); count++; } else { } } else { if (score.course.shi) { all += (int) ((float) score.pingshi * 0.3); all += (int) ((float) score.qimo * 0.7); count++; } else { count++; all += score.qimo; } } } } if (count == 0){ System.out.println(ban.code + " has no grades yet"); continue; } int val = (int) Math.floor(all / count); System.out.println(ban.code + " " + val); } } } class Course implements Comparable<Course>{ String name; Boolean bi; Boolean shi; public Course(String[] s) { name = s[0]; bi = s[1].equals("必修") ? true : false; if (s.length == 2 && bi) { shi = s[2].equals("考试") ? true : false; } else if (s.length == 3) { shi = s[2].equals("考试") ? true : false; } } @Override public int compareTo(Course o) { try { Comparator compator = Collator.getInstance(Locale.CHINA); if (compator.compare(name, o.name) < 0) { return -1; } else if (compator.compare(name, o.name) > 0) { return 1; } } catch (Exception e) { } return 0; } } class StudentScore { Student student = new Student(); Course course; int pingshi; int qimo; Ban ban = new Ban(); } class Ban implements Comparable<Ban> { Integer code; List<Student> students = new ArrayList<>(); @Override public int compareTo(Ban o) { return code - o.code; } } class Student implements Comparable<Student> { String name; Integer id; List<StudentScore> scores = new ArrayList<>(); @Override public int compareTo(Student o) { return this.id - o.id; } }
SourceMonitor上代码质量分析结果:
分析:
这段代码是一个课程成绩统计程序的实现。它使用Java语言编写,通过读取用户输入的信息来记录学生的课程成绩,并进行统计和输出。
代码主要逻辑在`main`方法中。首先,通过循环读取用户输入的每一行数据。根据输入的格式,判断是课程信息还是成绩信息。如果是课程信息,将其解析并存储到`courseMap`中;如果是成绩信息,将其解析并创建对应的`StudentScore`对象,然后存储到`scores`列表中。
在处理成绩信息时,通过调用`getStudent`和`getBan`方法获取或创建学生和班级对象,并将成绩信息与相应的学生、课程、班级关联起来。
接下来,通过遍历`students`列表,计算每个学生的平均成绩,并按照题目要求输出学生的学号、姓名和平均成绩。
然后,通过遍历`courseMap`中的课程信息,计算每门课程的平均分数,并按照题目要求输出课程的名称和平均分数。
最后,通过遍历`bans`列表,计算每个班级的平均成绩,并按照题目要求输出班级的编号和平均成绩。
整体而言,这段代码使用简单易懂的Java语言实现了课程成绩统计功能。通过合理的数据结构和逻辑处理,可以有效地记录、计算和输出学生的课程成绩信息。代码逻辑清晰,结构简洁,易于理解和使用。
SourceMonitor上代码质量分析结果:
- 代码结构良好,使用了合理的类和方法来组织逻辑。
- 代码中包含了注释,有助于理解和阅读代码。
- 使用了合适的数据结构来存储课程、学生和成绩信息。
- 代码中没有明显的错误或潜在问题。
- 对输入进行了一定程度的格式验证,但可能还可以进一步完善。
7-3 课程成绩统计程序-2
类图:
代码如下:
import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; import java.util.Locale; import java.util.Comparator; import java.text.Collator; 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 { int num = Integer.parseInt(a[3]); int [] aaa =new int[num]; for (int i = 0; i < aaa.length; i++) { aaa[i]=Integer.parseInt(a[i+4]); } score=new syScore(aaa,0,num); } 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("实验")&&items.length-4==Integer.parseInt(items[3])){ 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 int getScore(ArrayList<Choose> courseSelects)//实验 { int sum =0; for(Choose cs : courseSelects) { sum +=cs.score.getexperimentScore(); } return sum/courseSelects.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() + " " + getScore(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 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 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; } } abstract class Score{ public int Score2;//期末 public int totalScore; //public int totalScore1; public int getTotalScore() { return totalScore; } public int getFinalScore() { return Score2; } public int getexperimentScore() { return totalScore; } Score(int finalScore){this.Score2=finalScore;} } class ksScore extends Score{ private int Score1;//平时 public int getUsualScore() { return Score1; } ksScore(int usualScore, int finalScore){ super(finalScore); this.Score1=usualScore; this.totalScore=(int)(finalScore*0.7+usualScore*0.3); } } class kcScore extends Score{ kcScore(int finalScore){ super(finalScore); this.totalScore=finalScore; } } class syScore extends Score{ syScore(int [] a,int finalScore,int n){ super(finalScore); int sum=0; for (int i = 0; i <n; i++) { sum+=a[i]; } this.totalScore=sum/n; } } 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 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 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 scoreMatching1 = "([1-9]\\d{0,1}|0|100)( ([1-9]\\d{0,1}|0|100)){3,8}"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkcourseTypeMatching = "(考试|考察|实验)"; static String experimentNumber = "[4-9]"; //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 + " " + experimentNumber + " " +scoreMatching + " "+scoreMatching+ " "+scoreMatching; static String scoreInput3 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + experimentNumber +" "+scoreMatching1; 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)||s.matches(scoreInput3)); } }
SourceMonitor上代码质量分析结果:
分析:
代码的主要逻辑在Main
类中的main
方法中,通过Scanner
对象读取用户输入的每一行数据,并调用ParseInput
类的parseInput
方法进行解析和处理。根据不同的输入类型(课程信息或成绩信息),使用switch
语句进行相应的处理。
ParseInput
类包括了多个成员变量,分别存储课程、学生、选课和班级的信息列表。parseInput
方法根据输入类型选择不同的处理方式,并调用相应的方法来解析和存储信息。
Course
、Student
和myClass
类分别表示课程、学生和班级的信息,在这些类中定义了相应的属性和方法。
在处理成绩信息时,inputScore
方法根据输入的信息创建对应的Course
、Student
和Score
对象,并将其添加到相应的列表中。同时,它也会进行一些错误检查,如判断课程名称是否存在、成绩数量与考核方式是否匹配等。
在最后,根据题目要求,使用showStudents
、showCourses
和showClasses
方法分别输出学生、课程和班级的成绩信息。
整体而言,该代码实现了课程成绩统计程序的功能,通过多个类和方法进行数据的解析、存储和输出。代码中使用了合理的命名和注释,逻辑清晰,易于理解和维护。
SourceMonitor上代码质量分析结果:
- 代码结构相对清晰,逻辑较为简洁。
- 使用了正则表达式进行输入格式匹配,提高了数据处理的准确性。
- 通过引入新的类和方法,增加了代码的可读性和可维护性。
- 对输入进行了更全面的错误检查,提供了更友好的错误提示。
7-2 课程成绩统计程序-3
类图:
代码如下:
import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; import java.text.Collator; import java.util.Comparator; import java.util.Locale; 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 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 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 scoreMatching1 = "([1-9]\\d{0,1}|0|100)( ([1-9]\\d{0,1}|0|100)){1,9}"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String courseTypeMatching1 = "(选修|必修)"; static String checkcourseTypeMatching = "(考试|考察|实验)"; static String regex = "(\\d+\\.\\d+)( (\\d+\\.\\d+)){2,9}"; static String experimentNumber = "[4-9]"; static String qwer = "\\d+\\.\\d+"; //cousrInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching; static String courseInput0 = courseNameMatching + " " + courseTypeMatching1 + " " + "考试"+ " " + qwer + " " + qwer; static String courseInput1 = courseNameMatching + " " + "实验" + " " + "实验" + " " + experimentNumber + " " + regex; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching; static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching +" "+scoreMatching1; 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)||s.matches(courseInput1)||s.matches(courseInput0)); } private static boolean matchingScore(String s) { return (s.matches(scoreInput)||s.matches(scoreInput1)); } } class Course implements Comparable<Course>{ private String csName; private String csCharacter; private String csExamine; private int number; private double [] weight; public Course(String csName, String csCharacter, String csExamine,int number,double [] weight) { this.csName = csName; this.csCharacter = csCharacter; this.csExamine = csExamine; this.number = number; this.weight = weight; } public Course(String csName, String csCharacter, String csExamine,double [] weight) { this.csName = csName; this.csCharacter = csCharacter; this.csExamine = csExamine; this.weight = weight; } 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; } public int getNumber() { return number; } public double[] getWeight() { return weight; } @Override public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(Locale.CHINA); return compare.compare(csName,o.getCsName()); } } 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 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]),course.getWeight()); } else { int num = a.length-3; int [] flag =new int[num]; for (int i = 0; i < flag.length; i++) { flag[i]=Integer.parseInt(a[i+3]); } score=new syScore(flag,0,course.getWeight()); } if(existChooseCourse(student,course)) return; Choose chooseCourse = new Choose(course, student, score); chooseArrayList.add(chooseCourse); } public void inputCourse(String[] a){ Course course; double [] weight; if(a[2].equals("实验")&&a.length>7){ weight = syweight(a); course = new Course(a[0],a[1],a[2],Integer.parseInt(a[3]),weight); } else { if (a[2].equals("考试")&&a.length==5) { weight = ksweight(a); course = new Course(a[0], a[1], a[2], weight); } else course = new Course(a[0],a[1],a[2]); } if(getCourse(a[0])!=null) return; if(!checkCourse(a,course)) return; if(getCourse(a[0])==null&&a[2].equals("考察")&&a.length==3){ course=new Course(a[0], a[1], a[2]); courseArrayList.add(searchCourse(course)); } if(getCourse(a[0])==null&&a[2].equals("实验")&&a.length>=8){ weight = syweight(a); course=new Course(a[0], a[1], a[2],Integer.parseInt(a[3]),weight); courseArrayList.add(searchCourse(course)); } if(getCourse(a[0])==null&&a[2].equals("考试")&&a.length==5){ weight = ksweight(a); course=new Course(a[0], a[1], a[2],0,weight); courseArrayList.add(searchCourse(course)); } } double[] ksweight(String[] b){ double [] a = new double[2]; for (int i = 0; i < a.length; i++) { a[i]=Float.parseFloat(b[i+3]); } return a; } double [] syweight(String[] b){ double [] a = new double[Integer.parseInt(b[3])]; for (int i = 0; i < a.length; i++) { a[i]= Float.parseFloat(b[i+4]); } return a; } boolean checkCourse(String[] items,Course course){ if (items[2].equals("实验")&&items.length-4!=Integer.parseInt(items[3])){ System.out.println(course.getCsName() + " : number of scores does not match"); return false; } if (items[2].equals("实验")&&items.length-4==Integer.parseInt(items[3])){ int num = Integer.parseInt(items[3]); double sum=0; int [] flag =new int[num]; for (int i = 0; i < flag.length; i++) { sum+=Double.parseDouble(items[i+4]); } if(sum>1.000001||sum<0.999999){ System.out.println(course.getCsName() + " : weight value error"); return false; } } if (items[2].equals("考试")&&items.length==5){ double sum= 0; int [] flag =new int[2]; for (int i = 0; i < flag.length; i++) { sum+=Double.parseDouble(items[i+3]); } if(sum>1.000001||sum<0.999999){ System.out.println(course.getCsName() + " : weight value error"); return false; } } 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().getStNumber().equals(stu.getStNumber())) return true; } } return false; } Course searchCourse(Course course){ for (Choose choose : chooseArrayList) { if (choose.getCourse().getCsName().equals(course.getCsName())) { return null; } } return course; } 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("实验")&&items.length-3==course.getNumber()){ return true; } System.out.println(items[0]+" "+items[1]+" : access mode mismatch"); return false; } public int getAvgTotalScore(ArrayList<Choose> listChooseCourse) { int sum =0; for(Choose cs : listChooseCourse) { sum +=cs.score.getTotalScore(); } return sum/listChooseCourse.size(); } public int getScore(ArrayList<Choose> courseSelects)//实验 { float sum =0; for(Choose cs : courseSelects) { sum +=cs.score.getExperimentScore(); } return (int)(sum/courseSelects.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() + " " + getAvgTotalScore(CourseSelects)); if (course.getCsExamine().equals("考察")) System.out.println(course.getCsName() + " " + getAvgTotalScore(CourseSelects)); if (course.getCsExamine().equals("实验")) System.out.println(course.getCsName() + " " + getScore(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 Student implements Comparable<Student>{ private String stuNumber; 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()); } } abstract class Score{ public int Score2;//期末 public int totalScore; public float getTotalScore() { return totalScore; } public float getExperimentScore() { return totalScore; } Score(int finalScore){this.Score2=finalScore;} } class ksScore extends Score{//考试 private int Score1;//平时 ksScore(int usualScore, int finalScore,double [] b){ super(finalScore); this.Score1=usualScore; this.totalScore=(int)(Score1*b[0]+finalScore*b[1]); } } class kcScore extends Score{//考察 kcScore(int finalScore){ super(finalScore); this.totalScore=finalScore; } } class syScore extends Score{//实验 syScore(int [] a,int finalScore,double [] b){ super(finalScore); double sum=0; for (int i = 0; i <a.length; i++) { for (int j = 0; j < b.length; j++) { sum+=(a[i]*b[i]); } } this.totalScore= (int)sum/a.length; } }
SourceMonitor上代码质量分析结果:
分析:
这段代码是一个课程成绩统计程序的实现。它使用Java语言,通过读取用户输入的信息来记录课程和学生的成绩,并进行统计和输出。
主要逻辑在Main
类的main
方法中。它通过Scanner
对象读取用户输入的每一行数据,并交给ParseInput
类的parseInput
方法处理。根据输入类型(课程信息或成绩信息),调用相应的方法来解析和存储信息。
ParseInput
类包含了多个列表来存储课程、学生、选课和班级的信息。parseInput
方法根据输入的内容选择不同的处理方式,并将解析后的信息存储到相应的列表中。
在处理成绩信息时,inputScore
方法会根据输入的数据创建对应的Course
、Student
和Score
对象,并将其添加到相应的列表中。同时,还进行了一些错误检查,如判断课程是否存在、成绩数量是否匹配等。
最后,调用showStudents
、showCourses
和showClasses
方法按照题目要求输出学生、课程和班级的成绩信息。
整体而言,这段代码使用了简单易懂的Java语言来实现课程成绩统计功能。代码逻辑清晰,结构合理,易于理解和维护。
SourceMonitor上代码质量分析结果:
- 代码结构较为紧凑,逻辑清晰。
- 使用了集合类型和Stream API,简化了代码的编写和处理。
- 引入了新的类和方法,提高了代码的可拓展性和可复用性。
- 对输入进行了更加详细和全面的错误检查。
- 通过重构和优化,使得代码更加简洁、高效。
三、踩坑心得
-
题目:课程成绩统计程序
- 踩坑心得:在处理输入时,需要注意对数据格式的合法性进行验证,以避免无效或错误的输入导致程序异常。
- 潜在问题:代码中未对所有可能的非法输入进行全面的检查和处理,例如输入长度超过限制、输入范围不合理等。在实际应用中,应该更加严格地验证输入数据,并给出准确的错误提示。
-
题目:课程成绩统计程序的改进版
- 踩坑心得:使用正则表达式可以有效地匹配和验证输入格式,提高了数据处理的准确性和可靠性。
- 潜在问题:虽然使用了正则表达式进行输入验证,但仍然需要考虑到各种可能的输入情况。有些特殊情况可能无法通过简单的正则表达式来完全匹配,需要更全面地检查数据格式和范围。
-
题目:课程成绩统计程序的再次改进版
- 踩坑心得:使用集合类型和Stream API可以简化代码编写,并提高代码的可读性和可维护性。
- 潜在问题:虽然使用了集合类型和Stream API,但在处理大量数据时可能会影响性能。需要注意在实际应用中平衡代码的简洁性和性能需求,避免出现性能瓶颈。
四、改进建议
- 加强代码可读性和复用性:在编写代码时,应该遵循高内聚、低耦合的原则,将代码细分为一些独立的模块,减少重复代码和冗余代码。此外,通过好的命名方式和注释规范,能够有效提高代码可读性。
- 严格按照需求文档进行开发在编写代码之前,需要仔细阅读并理解需求文档的每个环节,审慎地思考其他模块之间的关系,确定所需的数据结构和算法。只有这样,才能切实有效地开发出符合要求的完整程序。对问题及时处理并推进项目进度在进行开发过程中,难免会遇到各种问题和挑战。良好的沟通协作是非常重要的,我们需要参与项目团队成员之间的讨论,共同找到最优解决方案,并及时处理问题以确保项目进度顺利。多掌握Java相关知识对于Java项目来说,更多的工具和技术链路会极大地提高代码效率。因此,在学习新的Java知识时,不妨尝试多做一些练习,比如熟悉集合框架、多线程编程、数据库操作等等,有助于更好地掌握Java相关知识。
- 不断接触新技术:Java 是一个广泛使用的编程语言,并且有很多与其匹配的开源技术。在学习Java时,需要考虑到前沿技术变化速度很快,千万不能只停留在表层。要不断地了解最新的 Java 技术和工具,跟上技术发展的步伐。
五、总结
在通过Java作业的练习中,我深刻认识到了程序设计的重要性和学习Java编程的必要性。
- 理解项目需求及实现功能的逻辑,在开始做项目之前,需要仔细阅读每一个模块的需求文档,并理解这些需求如何与整个项目相关联。如果在这个阶段的理解不到位,就可能会出现后期代码失控、需求变更难以承担等问题。
- 处理各种迭代和继承关系,秉承面向对象的编程思想,Java中存在大量的迭代和继承关系。这对于初学者来说,可能会有一定难度,主要体现在类的设计、抽象方法、多态性等方面。
- 代码优化和效率,在Java开发过程中,为了项目的长期稳定性和可维护性,需要注意代码质量和效率的问题。因此,在写代码的时候,必须考虑到封装性、可读性、面向对象、重用性等一系列因素。
我的心得感受:在完成这样的Java项目时,需要具备扎实的Java基础知识,并要注重系统性思考和分析能力。同时,还需要注重团队协作和积极沟通,特别是多人协作开发时,用好 Git 版本控制工具来管理项目是非常重要的。任何一个步骤的缺陷会影响到整个开发的过程,因此,在完成每个模块之后都应该进行测试,确保代码稳定可靠,增强开发者对代码合理性和实现逻辑的信心。tq