前言:
在这个六到八次题目集中,主要用课程管理系统来考察以下的知识点,:输入输出、字符串处理、数据结构(HashMap、ArrayList、List、Set)、循环、条件判断、类与对象、继承与多态、异常处理等。题量从小变大,难度大的也主要是那些学生课程成绩管理系统的解决,输入信息的解析和存储、成绩计算、信息展示,这些都是比较难的地方。
设计与分析:
第一道课程成绩管理系统题目的类图:

答题思路:首先,创建一个Scanner对象,用于读取用户输入的信息。
- 创建ParseInput、Show对象,用于解析输入信息和展示信息。
- 进入循环,不断读取用户输入的信息,直到用户输入"end"为止。
- 在循环中,将用户输入的信息传递给ParseInput对象的inputInformation方法进行解析和存储。
- 当用户输入"end"时,调用Show对象的showStudentInformation、showCourseInformation和showClassInformation方法,分别展示学生信息、课程信息和班级信息。
- 程序结束。
在ParseInput类中,根据输入的内容进行正则表达式匹配,判断输入的信息类型,并进行相应的处理。如果输入的信息格式有误,输出错误信息。如果输入的信息符合要求,将其存储到相应的数据结构中。
在Show类中,根据存储的信息,计算平均成绩并展示信息。首先根据学生ID对学生信息进行排序,然后计算每个学生的平均成绩并展示。然后根据课程名称对课程信息进行排序,计算每门课程的平均成绩并展示。最后根据班级号对班级信息进行排序,计算每个班级的平均成绩并展示。
代码分析:
import java.text.Collator;
import java.util.Comparator;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
public class Main{
public static void main(String[] args){
Scanner s=new Scanner(System.in);
String s_record=s.nextLine();
ParseInput handle=new ParseInput();
while(!s_record.equals("end")){
handle.parseInput(s_record);
s_record=s.nextLine();
}
handle.showStudents();
handle.showCourses();
handle.showClasses();
}
}
class Cls implements Comparable<Cls>{
String id;
ArrayList<Student> listStudent=new ArrayList<>();
public ArrayList<Student> getListStudent() {
return listStudent;
}
public String getId() {
return id;
}
void addStudent(Student stu){
listStudent.add(stu);
}
public void setId(String id) {
this.id = id;
}
public Cls(String id){
this.id=id;
}
@Override
public int compareTo(Cls o){
return id.compareTo(o.getId());
}
}
class Student implements Comparable<Student>{
String id;
Cls cls;
String name;
public Student(String name,String id){
this.name=name;
this.id=id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cls getCls() {
return cls;
}
public void setCls(Cls cls) {
this.cls = cls;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int compareTo(Student o){
return getId().compareTo(o.getId());
}
}
class ParseInput{
ArrayList<Course> listCourse=new ArrayList<>();
ArrayList<Student> listStudent=new ArrayList<>();
ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>();
ArrayList<Cls> listCls=new ArrayList<>();
public void parseInput(String s){
int i=InputMatching.matchingInput(s);
String[] items=s.split(" ");
switch(i){
case 0:
System.out.println("wrong format");
return;
case 1:
parseCourseRecord(items);
return;
case 2:
parseScoreRecord(items);
return;
}
}
Course getCourse(String courseName){
for (int i=0;i<listCourse.size();i++)
{
if(listCourse.get(i).getName().equals(courseName))
return listCourse.get(i);
}
return null;
}
Cls getCls(String clsId){
for(int i=0;i<listCls.size();i++){
if(listCls.get(i).getId().equals(clsId))
return listCls.get(i);
}
return null;
}
Student getStudent(String stuId){
for(int i=0;i<listStudent.size();i++)
{
if(listStudent.get(i).getId().equals(stuId))
{
return listStudent.get(i);
}
}
return null;
}
private void parseCourseRecord(String[] items){
String courseName=items[0];
String courseType=items[1];
String checkType=items[2];
Course course=new Course(courseName,courseType,checkType);
if(!checkCourse(course))
return;
if(getCourse(courseName)==null){
course=new Course(courseName,courseType,checkType);
listCourse.add(course);
}
}
boolean checkCourse(Course course){
int courseTp,accessTp;
switch (course.getType()){
case "必修":
courseTp=0;
break;
case "选修":
courseTp=1;
break;
default:
courseTp=-1;
}
switch (course.getMethod()){
case"考试":
accessTp=0;
break;
case"考察":
accessTp=1;
break;
default:
accessTp=-1;
}
if(courseTp==0&&(accessTp==0))
return true;
if(courseTp==1&&(accessTp==0||accessTp==1))
return true;
System.out.println(course.getName()+" : course type & access mode mismatch");
return false;
}
private void parseScoreRecord(String[] items){
String stuId=items[0];
String stuName=items[1];
String courseName=items[2];
String clsId=stuId.substring(0,6);
Cls cls;
Student stu;
cls=getCls(clsId);
if(cls==null){
cls=new Cls(clsId);
listCls.add(cls);
}
stu=getStudent(stuId);
if(stu==null){
stu=new Student(stuName,stuId);
listStudent.add(stu);
cls.addStudent(stu);
}
stu.setCls(cls);
Course course=getCourse(courseName);
if(course==null){
System.out.println(courseName+" does not exist");
return;
}
if(!checkGrade(items,course))
return;
Grade grade;
if(items.length==4){
int finalScore=Integer.parseInt(items[3]);
grade=new AssessmentGrade(finalScore);
}else {
int usualScore=Integer.parseInt(items[3]);
int finalScore=Integer.parseInt(items[4]);
grade=new ExaminationGrade(usualScore,finalScore);
}
if(existChooseCourse(stu,course)) return;
ChooseCourse chooseCourse=new ChooseCourse(course,stu,grade);
listChooseCourse.add(chooseCourse);
}
boolean existChooseCourse(Student stu,Course course){
for(int i=0;i<listChooseCourse.size();i++){
if(listChooseCourse.get(i).getCourse().getName().equals(course.getName())) {
if (listChooseCourse.get(i).getStudent().getName().equals(stu.getName()))
return true;
}
}
return false;
}
private boolean checkGrade(String[] items,Course course){
String courseType=course.getMethod();
if(courseType.equals("考试")&&items.length==5){
return true;
}
if(courseType.equals("考察")&&items.length==4){
return true;
}
System.out.println(items[0]+" "+items[1]+" : access mode mismatch");
return false;
}
public void showStudents(){
Collections.sort(listStudent);
for(int i =0;i<listStudent.size();i++)
{
Student stu=listStudent.get(i);
ArrayList<ChooseCourse> stuCourseSelects =getStudentSelects(stu.getId());
if(stuCourseSelects.size()!=0)
{
System.out.println(stu.getId() + " "+ stu.getName()+" "+getAvgTotalScore(stuCourseSelects));
}
else
{
System.out.println(stu.getId() +" "+stu.getName()+ ""+ " did not take any exams");
}
}
}
public void showCourses(){
Collections.sort(listCourse);
for(int i =0;i<listCourse.size();i++)
{
Course course = listCourse.get(i);
ArrayList<ChooseCourse> courseSelects = getCourseSelects(course.getName());
if(courseSelects.size()== 0)
{
System.out.println(course.getName() + " has no grades yet");
}
else {
if(course.getMethod().equals("考试"))
{
System.out.println(course.getName() + " " +getAvgUsualScore(courseSelects)+ " "+getAvgFinalScore(courseSelects)+ " "+getAvgTotalScore(courseSelects));
}else{
System.out.println(course.getName() + " "+getAvgFinalScore(courseSelects)+ " "+getAvgTotalScore(courseSelects));
}
}
}
}
public void showClasses(){
Collections.sort(listCls);
for(int i =0;i<listCls.size();i++)
{
Cls cls = listCls.get(i);
ArrayList<ChooseCourse> classCourseSelects = getClassSelects(cls.getId());
if(classCourseSelects.size()==0){
System.out.println(cls.getId()+" has no grades yet");
}
else{
System.out.println(cls.getId()+" "+ getAvgTotalScore(classCourseSelects));
}
}
}
public static int getAvgUsualScore(ArrayList<ChooseCourse> courseSelects)
{
int sum = 0;
for(ChooseCourse cs : courseSelects)
{
sum +=((ExaminationGrade) cs.grade).getUsualScore();
}
return sum/courseSelects.size();
}
public int getAvgTotalScore(ArrayList<ChooseCourse> listChooseCourse)
{
int sum =0;
for(ChooseCourse cs : listChooseCourse)
{
sum +=cs.grade.getTotalScore();
}
int s = sum/listChooseCourse.size();
return s;
}
public int getAvgFinalScore(ArrayList<ChooseCourse> courseSelects)
{
int sum =0;
for(ChooseCourse cs : courseSelects)
{
sum +=cs.grade.getFinalScore();
}
int s = sum/courseSelects.size();
return s;
}
public ArrayList<ChooseCourse> getClassSelects(String className){
Cls cls=getCls(className);
ArrayList<ChooseCourse> classSelects = new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (className.equals(cs.getStudent().cls.getId())){
classSelects.add(cs);
}
}
return classSelects;
}
public ArrayList<ChooseCourse> getStudentSelects(String stuId) {
ArrayList<ChooseCourse> stuSelects = new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (stuId.equals(cs.student.getId())){
stuSelects.add(cs);
}
}
return stuSelects;
}
public ArrayList<ChooseCourse> getCourseSelects(String courseName){
ArrayList<ChooseCourse> courseSelect=new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (courseName.equals(cs.course.getName())){
courseSelect.add(cs);
}
}
return courseSelect;
}
}
class ChooseCourse{
Course course;
Student student;
Grade grade;
public ChooseCourse(Course course, Student student, Grade grade) {
this.course=course;
this.grade=grade;
this.student=student;
}
public Grade getGrade() {
return grade;
}
public Student getStudent() {
return student;
}
public Course getCourse() {
return course;
}
}
class InputMatching {
static String stuNumMatching = "\\d{8}";//8个0-9的数字
static String stuNameMatching = "[^ \\t]{1,10}";//1到10个非空格(TAB)字符
static String scoreMatching = "([1-9]?[0-9]|100)";
static String courseNameMatching = "[^ \\t]{1,10}";//1到10个非空格(TAB)字符
static String courseTypeMatching = "(选修|必修)";
static String checkcourseTypeMatching = "(考试|考察)";
static String scoreMatching1 = "(\\s([1-9]?[0-9]|100))?";
//cousrInput用于定义课程信息模式(正则表达式)
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
//scoreInput用于定义成绩信息模式(正则表达式)
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + 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) {
// System.out.println(match);
return s.matches(scoreInput);
}
}
class Course implements Comparable<Course>{
String name;
String type;
String method;
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Course(String name,String type){
this.type = type;
this.name = name;
}
public Course(String name,String type,String method){
this.name=name;
this.type=type;
this.method=method;
}
@Override
public int compareTo(Course o){
Comparator<Object> compare=Collator.getInstance(java.util.Locale.CHINA);
return compare.compare(name,o.getName());
}
}
abstract class Grade{
protected int finalScore;
protected int totalScore;
public int getTotalScore() {
return totalScore;
}
public int getFinalScore() {
return finalScore;
}
Grade(int finalScore){this.finalScore=finalScore;}
}
class ExaminationGrade extends Grade{
private int usualScore;
public int getUsualScore() {
return usualScore;
}
ExaminationGrade(int usualScore, int finalScore){
super(finalScore);
this.usualScore=usualScore;
this.totalScore=(int)(finalScore*0.7+usualScore*0.3);
}
}
class AssessmentGrade extends Grade{
AssessmentGrade(int finalScore){
super(finalScore);
this.totalScore=finalScore;
}
}
以上的代码主要是从三部分写起输入信息解析、数据存储和展示信息。分三部分进行思考,每一部分是一个大类,然后从再细分下面的类,用简单的类来进行调用,进而实现这个课程管理系统。主方法中,通过Scanner对象读取用户输入的信息,并创建ParseInput对象进行解析和存储。通过循环读取输入信息,直到输入"end"为止。最后调用ParseInput对象的展示方法,展示学生、课程和班级的相关信息。
- ParseInput类中,定义了ArrayList类型的变量listCourse、listStudent、listChooseCourse和listCls,分别用于存储课程信息、学生信息、选课信息和班级信息。在parseInput方法中,根据输入的信息类型进行相应的处理。parseCourseRecord方法用于解析课程信息,将课程信息存储到listCourse中。parseScoreRecord方法用于解析成绩信息,将成绩信息存储到listChooseCourse中。checkCourse方法用于检查课程类型和考试类型是否匹配。存在一些辅助方法,如getCourse、getCls和getStudent,用于根据课程名、班级号和学生ID获取相应的课程、班级和学生对象。showStudents、showCourses和showClasses方法用于展示学生、课程和班级的相关信息。
- Cls类表示班级,包括班级号和学生列表。Student类表示学生,包括学生ID、班级和姓名。Course类表示课程,包括课程名、课程类型和考试类型。ChooseCourse类表示选课记录,包括课程、学生和成绩。
- InputMatching类用于匹配输入的信息格式,根据正则表达式进行匹配判断。
- Grade类是一个抽象类,表示成绩,包括总成绩和最终成绩。ExaminationGrade和AssessmentGrade是Grade的子类,分别表示考试成绩和考察成绩。
第二到题目的类图:

代码分析:
import java.text.Collator;
import java.util.Comparator;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
public class Main{
public static void main(String[] args){
Scanner s=new Scanner(System.in);
String s_record=s.nextLine();
ParseInput handle=new ParseInput();
while(!s_record.equals("end")){
handle.parseInput(s_record);
s_record=s.nextLine();
}
handle.showStudents();
handle.showCourses();
handle.showClasses();
}
}
class Cls implements Comparable<Cls>{
String id;
ArrayList<Student> listStudent=new ArrayList<>();
public ArrayList<Student> getListStudent() {
return listStudent;
}
public String getId() {
return id;
}
void addStudent(Student stu){
listStudent.add(stu);
}
public void setId(String id) {
this.id = id;
}
public Cls(String id){
this.id=id;
}
@Override
public int compareTo(Cls o){
return id.compareTo(o.getId());
}
}
class Student implements Comparable<Student>{
String id;
Cls cls;
String name;
public Student(String name,String id){
this.name=name;
this.id=id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cls getCls() {
return cls;
}
public void setCls(Cls cls) {
this.cls = cls;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int compareTo(Student o){
return getId().compareTo(o.getId());
}
}
class ParseInput{
ArrayList<Course> listCourse=new ArrayList<>();
ArrayList<Student> listStudent=new ArrayList<>();
ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>();
ArrayList<Cls> listCls=new ArrayList<>();
public void parseInput(String s){
String[] items=s.split(" ");
if(items.length<=5) {
int i = InputMatching.matchingInput(s);
switch (i) {
case 0:
System.out.println("wrong format");
return;
case 1:
parseCourseRecord(items);
return;
case 2:
parseScoreRecord(items);
return;
}
}else {
int i = InputMatching.matchingInput1(s);
switch (i) {
case 0:
System.out.println("wrong format");
return;
case 1:
parseCourseRecord(items);
return;
case 2:
parseScoreRecord(items);
return;
}
}
}
Course getCourse(String courseName){
for (int i=0;i<listCourse.size();i++)
{
if(listCourse.get(i).getName().equals(courseName))
return listCourse.get(i);
}
return null;
}
Cls getCls(String clsId){
for(int i=0;i<listCls.size();i++){
if(listCls.get(i).getId().equals(clsId))
return listCls.get(i);
}
return null;
}
Student getStudent(String stuId){
for(int i=0;i<listStudent.size();i++)
{
if(listStudent.get(i).getId().equals(stuId))
{
return listStudent.get(i);
}
}
return null;
}
private void parseCourseRecord(String[] items){
String courseName=items[0];
String courseType=items[1];
String checkType=items[2];
Course course=new Course(courseName,courseType,checkType);
if(!checkCourse(course))
return;
if(getCourse(courseName)==null){
course=new Course(courseName,courseType,checkType);
listCourse.add(course);
}
}
boolean checkCourse(Course course){
int courseTp,accessTp;
switch (course.getType()){
case "必修":
courseTp=0;
break;
case "选修":
courseTp=1;
break;
case "实验":
courseTp = 2;
break;
default:
courseTp=-1;
}
switch (course.getMethod()){
case"考试":
accessTp=0;
break;
case"考察":
accessTp=1;
break;
case"实验":
accessTp=2;
break;
default:
accessTp=-1;
}
if(courseTp==0&&(accessTp==0))
return true;
if(courseTp==1&&(accessTp==0||accessTp==1))
return true;
if(courseTp==2&&(accessTp==2))
return true;
System.out.println(course.getName()+" : course type & access mode mismatch");
return false;
}
private void parseScoreRecord(String[] items){
String stuId=items[0];
String stuName=items[1];
String courseName=items[2];
String clsId=stuId.substring(0,6);
Cls cls;
Student stu;
cls=getCls(clsId);
if(cls==null){
cls=new Cls(clsId);
listCls.add(cls);
}
stu=getStudent(stuId);
if(stu==null){
stu=new Student(stuName,stuId);
listStudent.add(stu);
cls.addStudent(stu);
}
stu.setCls(cls);
Course course=getCourse(courseName);
if(course==null){
System.out.println(courseName+" does not exist");
return;
}
if(!checkGrade(items,course))
return;
Grade grade;
if(items.length==4){
int finalScore=Integer.parseInt(items[3]);
grade=new AssessmentGrade(finalScore);
}else if(items.length==5){
int usualScore=Integer.parseInt(items[3]);
int finalScore=Integer.parseInt(items[4]);
grade=new ExaminationGrade(usualScore,finalScore);
}else {
int experimentScore;
int sum=0;
for(int i =4;i<items.length;i++)
{
sum+=Integer.parseInt(items[i]);
}
experimentScore=sum/Integer.parseInt(items[3]);
grade=new ExperimentGrade(experimentScore);
}
if(existChooseCourse(stu,course)) return;
ChooseCourse chooseCourse=new ChooseCourse(course,stu,grade);
listChooseCourse.add(chooseCourse);
}
boolean existChooseCourse(Student stu,Course course){
for(int i=0;i<listChooseCourse.size();i++){
if(listChooseCourse.get(i).getCourse().getName().equals(course.getName())) {
if (listChooseCourse.get(i).getStudent().getName().equals(stu.getName()))
return true;
}
}
return false;
}
private boolean checkGrade(String[] items,Course course){
String courseType=course.getMethod();
if(courseType.equals("考试")&&items.length==5){
return true;
}
if(courseType.equals("考察")&&items.length==4){
return true;
}
if(courseType.equals("实验")&&Integer.parseInt(items[3])==(items.length-4)&&items.length<=13)
return true;
System.out.println(items[0]+" "+items[1]+" : access mode mismatch");
return false;
}
public void showStudents(){
Collections.sort(listStudent);
for(int i =0;i<listStudent.size();i++)
{
Student stu=listStudent.get(i);
ArrayList<ChooseCourse> stuCourseSelects =getStudentSelects(stu.getId());
if(stuCourseSelects.size()!=0)
{
System.out.println(stu.getId() + " "+ stu.getName()+" "+getAvgTotalScore(stuCourseSelects));
}
else
{
System.out.println(stu.getId() +" "+stu.getName()+ ""+ " did not take any exams");
}
}
}
public void showCourses(){
Collections.sort(listCourse);
for(int i =0;i<listCourse.size();i++)
{
Course course = listCourse.get(i);
ArrayList<ChooseCourse> courseSelects = getCourseSelects(course.getName());
if(courseSelects.size()== 0)
{
System.out.println(course.getName() + " has no grades yet");
}
else {
if(course.getMethod().equals("考试"))
{
System.out.println(course.getName() + " " +getAvgUsualScore(courseSelects)+ " "+getAvgFinalScore(courseSelects)+ " "+getAvgTotalScore(courseSelects));
}else if(course.getMethod().equals("考察")){
System.out.println(course.getName() + " "+getAvgFinalScore(courseSelects)+ " "+getAvgTotalScore(courseSelects));
}
else
{
System.out.println(course.getName()+" "+getExperimentScore(courseSelects));
}
}
}
}
// private String getExperimentScore(ArrayList<ChooseCourse> courseSelects) {
// // TODO 自动生成的方法存根
// return null;
// }
//
public void showClasses(){
Collections.sort(listCls);
for(int i =0;i<listCls.size();i++)
{
Cls cls = listCls.get(i);
ArrayList<ChooseCourse> classCourseSelects = getClassSelects(cls.getId());
if(classCourseSelects.size()==0){
System.out.println(cls.getId()+" has no grades yet");
}
else{
System.out.println(cls.getId()+" "+ getAvgTotalScore(classCourseSelects));
}
}
}
private int getExperimentScore(ArrayList<ChooseCourse> courseSelects) {
// TODO 自动生成的方法存根
int sum = 0;
for(ChooseCourse cs : courseSelects) {
sum += cs.grade.getExperimentScore();
}
return sum/courseSelects.size();
}
public static int getAvgUsualScore(ArrayList<ChooseCourse> courseSelects)
{
int sum = 0;
for(ChooseCourse cs : courseSelects)
{
sum +=((ExaminationGrade) cs.grade).getUsualScore();
}
return sum/courseSelects.size();
}
public int getAvgTotalScore(ArrayList<ChooseCourse> listChooseCourse)
{
int sum =0;
for(ChooseCourse cs : listChooseCourse)
{
sum +=cs.grade.getTotalScore();
}
int s = sum/listChooseCourse.size();
return s;
}
public int getAvgFinalScore(ArrayList<ChooseCourse> courseSelects)
{
int sum =0;
for(ChooseCourse cs : courseSelects)
{
sum +=cs.grade.getFinalScore();
}
int s = sum/courseSelects.size();
return s;
}
public ArrayList<ChooseCourse> getClassSelects(String className){
Cls cls=getCls(className);
ArrayList<ChooseCourse> classSelects = new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (className.equals(cs.getStudent().cls.getId())){
classSelects.add(cs);
}
}
return classSelects;
}
public ArrayList<ChooseCourse> getStudentSelects(String stuId) {
ArrayList<ChooseCourse> stuSelects = new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (stuId.equals(cs.student.getId())){
stuSelects.add(cs);
}
}
return stuSelects;
}
public ArrayList<ChooseCourse> getCourseSelects(String courseName){
ArrayList<ChooseCourse> courseSelect=new ArrayList<>();
for (ChooseCourse cs : listChooseCourse) {
if (courseName.equals(cs.course.getName())){
courseSelect.add(cs);
}
}
return courseSelect;
}
}
class ChooseCourse{
Course course;
Student student;
Grade grade;
public ChooseCourse(Course course, Student student, Grade grade) {
this.course=course;
this.grade=grade;
this.student=student;
}
public Grade getGrade() {
return grade;
}
public Student getStudent() {
return student;
}
public Course getCourse() {
return course;
}
}
class InputMatching {
static String stuNumMatching = "\\d{8}";//8个0-9的数字
static String stuNameMatching = "[^ \\t]{1,10}";//1到10个非空格(TAB)字符
static String scoreMatching = "([1-9]?[0-9]|100)";
static String courseNameMatching = "[^ \\t]{1,10}";//1到10个非空格(TAB)字符
static String experimentNumber = "([4-9])";
static String courseTypeMatching = "(选修|必修|实验)";
static String checkcourseTypeMatching = "(考试|考察|实验)";
static String scoreMatching1 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching2 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching3 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching4 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching5 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching6 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching7 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching8 = "(\\s([1-9]?[0-9]|100))?";
static String scoreMatching9 = "(\\s([1-9]?[0-9]|100))?";
//cousrInput用于定义课程信息模式(正则表达式)
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
//scoreInput用于定义成绩信息模式(正则表达式)
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + scoreMatching1;
static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
experimentNumber + scoreMatching1+scoreMatching2+scoreMatching3+scoreMatching4+scoreMatching5+scoreMatching6+scoreMatching7+scoreMatching8+scoreMatching9;
public static int matchingInput(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore(s)) {
return 2;
}
return 0;
}
public static int matchingInput1(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore1(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);
}
private static boolean matchingScore1(String s) {
return s.matches(scoreInput1);
}
}
class Course implements Comparable<Course>{
String name;
String type;
String method;
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Course(String name,String type){
this.type = type;
this.name = name;
}
public Course(String name,String type,String method){
this.name=name;
this.type=type;
this.method=method;
}
@Override
public int compareTo(Course o){
Comparator<Object> compare=Collator.getInstance(java.util.Locale.CHINA);
return compare.compare(name,o.getName());
}
}
abstract class Grade{
protected int finalScore;
protected int totalScore;
protected int experimentScore;
public int getExperimentScore() {
return experimentScore;
}
public int getTotalScore() {
return totalScore;
}
public int getFinalScore() {
return finalScore;
}
Grade(int finalScore)
{
this.finalScore=finalScore;
}
}
class ExperimentGrade extends Grade{
ExperimentGrade(int experimentScore){
super(experimentScore);
this.experimentScore=experimentScore;
this.totalScore=experimentScore;
}
}
class ExaminationGrade extends Grade{
private int usualScore;
public int getUsualScore() {
return usualScore;
}
ExaminationGrade(int usualScore, int finalScore){
super(finalScore);
this.usualScore=usualScore;
this.totalScore=(int)(finalScore*0.7+usualScore*0.3);
}
}
class AssessmentGrade extends Grade{
AssessmentGrade(int finalScore){
super(finalScore);
this.totalScore=finalScore;
}
}
这个代码是第一道代码的迭代,增加了实验课的成绩计算,之后再用正则表达式把实验课的各个东西给规定好,具体与上面的东西不一样的之处是在ParseInput类中,新增了对实验成绩的处理。通过修改InputMatching类的正则表达式,实现了对实验成绩的匹配和解析。新增了ExperimentGrade类,表示实验成绩,并在parseScoreRecord方法中进行实验成绩的解析和存储。
修改了Grade类的结构,添加了实验成绩的属性和相关的方法。
修改了checkCourse方法,增加了对实验课程的检查。
修改了showCourses方法,增加了对实验课程成绩的展示。
修改了InputMatching类,新增了matchingInput1方法,用于匹配实验成绩的输入信息。
第三道点菜题目类图:
代码分析:import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ParseInput parseInput = new ParseInput();
Show show = new Show();
while (true) {
String s = in.nextLine();
if (s.equals("end")) {
show.showStudentInformation(parseInput.listStudent, parseInput.electedCourses);
show.showCourseInformation(parseInput.listChooseCourse, parseInput.electedCourses);
show.showClassInformation(parseInput.listCourse, parseInput.electedCourses);
break;
}
parseInput.inputInformation(s);
}
}
}
class Class {
String classNum;
HashMap<String, Student> students;
public Class(String classNum){
this.classNum = classNum;
}
}
class Student {
String studentId;
String studentName;
public Student(String studentId, String studentName) {
this.studentId = studentId;
this.studentName = studentName;
}
}
class Course {
String courseName;
String courseType; //必修课还是选修课
String examType; //考试课还是考察课
float usualWeight;
float finalWeight;
ArrayList<Float> gradeWeight = new ArrayList<>();
int weightCount; //针对实验课设置的权重数量
public Course(String courseName, String courseType, String examType, float usualWeight, float finalWeight) {
this.courseName = courseName;
this.courseType = courseType;
this.examType = examType;
this.usualWeight = usualWeight;
this.finalWeight = finalWeight;
}
public Course(String courseName, String courseType, String examType) {
this.courseName = courseName;
this.courseType = courseType;
this.examType = examType;
}
public Course(String courseName, String courseType, String examType,ArrayList<Float> gradeWeight,int weightCount){
this.courseName = courseName;
this.courseType = courseType;
this.examType = examType;
this.gradeWeight = gradeWeight;
this.weightCount = weightCount;
}
}
class ElectedCourse {
Student student;
Course course;
Grade grade;
public ElectedCourse(Student student, Course course, Grade grade) {
this.student = student;
this.course = course;
this.grade = grade;
}
}
abstract class Grade {
float totalGrade;
public abstract void getTotalGrade();
}
class ExaminationGrade extends Grade {
int usualGrade;
int finalGrade;
float usualWeight;
float finalWeight;
@Override
public void getTotalGrade() {
totalGrade = usualGrade * usualWeight + finalGrade * finalWeight;
}
public ExaminationGrade(int usualGrade, int finalGrade, float usualWeight, float finalWeight) {
this.usualGrade = usualGrade;
this.finalGrade = finalGrade;
this.usualWeight = usualWeight;
this.finalWeight = finalWeight;
}
}
class AssessmentGrade extends Grade {
int finalGrade;
@Override
public void getTotalGrade() {
totalGrade = finalGrade;
}
public AssessmentGrade(int finalGrade) {
this.finalGrade = finalGrade;
}
}
class ExperimentGrade extends Grade {
List<Integer> gradeList;
ArrayList<Float> gradeWeight;
@Override
public void getTotalGrade() {
float sum = 0;
int i = 0;
for (Integer integer : gradeList) {
sum += integer * gradeWeight.get(i);
i++;
}
totalGrade = sum;
}
public ExperimentGrade(List<Integer> gradeList, ArrayList<Float> gradeWeight) {
this.gradeList = gradeList;
this.gradeWeight = gradeWeight;
}
}
class ParseInput {
HashMap<String, Class> listCourse = new HashMap<>();
HashMap<String, Student> listStudent = new HashMap<>();
HashMap<String, Course> listChooseCourse = new HashMap<>();
ArrayList<ElectedCourse> electedCourses = new ArrayList<>();
public void inputInformation(String s) {
String[] idems = s.split(" ");
if (s.matches("(\\S{1,10})( )(((选修)( )(实验)).*|((必修)( )(考察|实验)).*|((实验)( )(考试|考察)).*)")) {
System.out.println(idems[0] + " : course type & access mode mismatch");
}
if (s.matches("((\\S{1,10})( )(选修)( )(考试|考察).*)|((\\S{1,10})( )(必修)( )(考试).*)|((\\S{1,10})( )(实验)( )(实验)( )([4-9]).*)")) {
//课程信息
if (s.matches("(\\S{1,10})( )(((选修)( )(考察))|((必修|选修)( )(考试)( )([01])(.)(\\d)( )([01])(.)(\\d)))")) {
String courseName = idems[0];
String courseType = idems[1];
String examType = courseType.equals("必修") ? "考试" : idems[2];
if (listChooseCourse.containsKey(courseName)) {
return;
}
if (examType.equals("考试")) {
float usualWeight = Float.parseFloat(idems[3]);
float finalWeight = Float.parseFloat(idems[4]);
if (usualWeight + finalWeight != 1.0) {
System.out.println(courseName + " : weight value error");
return;
}
listChooseCourse.put(courseName, new Course(courseName, courseType, examType, usualWeight, finalWeight));
} else {
listChooseCourse.put(courseName, new Course(courseName, courseType, examType, 0, 1));
}
}
//实验课程信息
else if (s.matches("(\\S{1,10})( )(实验)( )(实验)( )([4-9])( )((0.)(\\d)( ))*(0.)(\\d)")) {
String courseName = idems[0];
String courseType = idems[1];
String examType = "实验";
if (listChooseCourse.containsKey(courseName)) {
return;
}
int amount = Integer.parseInt(idems[3]);
if (idems.length != (4 + amount)) {
System.out.println(courseName + " : number of scores does not match");
return;
}
float sum = 0;
for (int i = 0; i < amount; i++) {
sum += Float.parseFloat(idems[4 + i]);
}
if (sum > 0.99 && sum < 1.01) {
ArrayList<Float> gradeWeight = new ArrayList<>();
for (int i = 0; i < amount; i++) {
gradeWeight.add(Float.parseFloat(idems[4 + i]));
}
listChooseCourse.put(courseName, new Course(courseName, courseType, examType, gradeWeight, amount));
} else {
System.out.println(courseName + " : weight value error");
}
} else {
System.out.println("wrong format");
}
}
//学生信息
else if (s.matches("\\d{8} \\S{1,10} \\S{1,10}.*")) {
for (int i = 3; i < idems.length; i++)
if (!idems[i].matches("[0-9]|[1-9][0-9]|100")) {
System.out.println("wrong format");
return;
}
if (s.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )([0-9]|[1-9][0-9]|100)(( )([0-9]|[1-9][0-9]|100))?")) {
if (s.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )(\\d{1,2}|(100))(( )(\\d{1,2}|(100)))?")) {
String studentId = idems[0];
String studentName = idems[1];
String courseName = idems[2];
// for (ElectedCourse electedCourse : electedCourses) {
// if (electedCourse.student.studentId.equals(studentId) && electedCourse.course.courseName.equals(courseName)) {
// return;
// }
// }
boolean exists = electedCourses.stream()
.anyMatch(electedCourse -> electedCourse.student.studentId.equals(studentId) && electedCourse.course.courseName.equals(courseName));
if (exists) {
return;
}
listStudent.put(studentId, new Student(studentId, studentName));
String classNum = studentId.substring(0, 6);
listCourse.computeIfAbsent(classNum, key -> {
Class newClass = new Class(classNum);
newClass.students = new HashMap<>();
return newClass;
});
listCourse.get(classNum).students.put(studentId, new Student(studentId, studentName));
if (!listChooseCourse.containsKey(courseName)) {
System.out.println(courseName + " does not exist");
return;
}
if ((listChooseCourse.get(courseName).examType.equals("考察") && idems.length == 5) || (listChooseCourse.get(courseName).examType.equals("考试") && idems.length == 4)) {
System.out.println(studentId + " " + studentName + " : access mode mismatch");
return;
}
if (listChooseCourse.get(courseName).examType.equals("实验")) {
System.out.println(studentId + " " + studentName + " : access mode mismatch");
return;
}
String courseType = listChooseCourse.get(courseName).courseType;
String examType = listChooseCourse.get(courseName).examType;
int finalGrade = idems.length == 4 ? Integer.parseInt(idems[3]) : Integer.parseInt(idems[4]);
float finalWeight = listChooseCourse.get(courseName).finalWeight;
if (idems.length == 5) {
int usualGrade = Integer.parseInt(idems[3]);
float usualWeight = listChooseCourse.get(courseName).usualWeight;
electedCourses.add(new ElectedCourse(
new Student(studentId, studentName),
new Course(courseName, courseType, examType),
new ExaminationGrade(usualGrade, finalGrade, usualWeight, finalWeight)
));
} else if (idems.length == 4) {
electedCourses.add(new ElectedCourse(
new Student(studentId, studentName),
new Course(courseName, courseType, examType),
new AssessmentGrade(finalGrade)
));
}
}
}
//上实验的学生
else if (s.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )((\\d{1,2}|(100))( ))*(\\d{1,2}|(100))")) {
String studentId = idems[0];
String studentName = idems[1];
String courseName = idems[2];
for (ElectedCourse electedCourse : electedCourses) {
if (electedCourse.student.studentId.equals(studentId) && electedCourse.course.courseName.equals(courseName)) {
return;
}
}
listStudent.put(studentId, new Student(studentId, studentName));
String classNum = studentId.substring(0, 6);
if (!listCourse.containsKey(classNum)) {
listCourse.put(classNum, new Class(classNum));
listCourse.get(classNum).students = new HashMap<>();
}
listCourse.get(classNum).students.put(studentId, new Student(studentId, studentName));
if (!listChooseCourse.containsKey(courseName)) {
System.out.println(courseName + " does not exist");
return;
}
int count = listChooseCourse.get(courseName).weightCount;
if (idems.length != (3 + count)) {
System.out.println(studentId + " " + studentName + " : access mode mismatch");
return;
}
List<Integer> gradeList = new ArrayList<>();
for (int i = 0; i < count; i++) {
gradeList.add(Integer.parseInt(idems[3 + i]));
}
ArrayList<Float> gradeWeight = listChooseCourse.get(courseName).gradeWeight;
String courseType = listChooseCourse.get(courseName).courseType;
String examType = listChooseCourse.get(courseName).examType;
electedCourses.add(new ElectedCourse(new Student(studentId, studentName), new Course(courseName, courseType, examType), new ExperimentGrade(gradeList, gradeWeight)));
} else {
System.out.println("wrong format");
}
} else {
System.out.println("wrong format");
}
}
}
class Show {
public void showStudentInformation(HashMap<String, Student> students, ArrayList<ElectedCourse> electedCourses) {
Set<String> studentIds = students.keySet();
Set<String> sortSet = new TreeSet<>(String::compareTo);
sortSet.addAll(studentIds);
for (String studentId : sortSet) {
float sum = 0;
int count = 0;
for (ElectedCourse electedCourse : electedCourses) {
if (electedCourse.student.studentId.equals(students.get(studentId).studentId)) {
count++;
electedCourse.grade.getTotalGrade();
sum += electedCourse.grade.totalGrade;
}
}
if (count == 0) {
Student student = students.get(studentId);
System.out.println(student.studentId + " " + student.studentName + " did not take any exams");
continue;
}
int average = (int) (sum / count);
Student student = students.get(studentId);
System.out.println(student.studentId + " " + student.studentName + " " + average);
}
}
public void showCourseInformation(HashMap<String, Course> courses, ArrayList<ElectedCourse> electedCourses) {
List<String> courseNames = new ArrayList<>(courses.keySet());
courseNames.sort((o1, o2) -> {
Comparator<Object> compare = Collator.getInstance(Locale.CHINA);
return compare.compare(o1, o2);
});
for (String courseName : courseNames) {
int courseNumber = -1, sum = 0, examNumber = -1, examSum = 0, experimentAverage, experimentCount = -1;
for (ElectedCourse electedCourse : electedCourses) {
if (electedCourse.course.courseName.equals(courses.get(courseName).courseName)) {
if (courseNumber == -1) courseNumber = 0;
if (electedCourse.course.courseType.equals("考试") && examNumber == -1) {
examNumber = 0;
}
if (electedCourse.course.courseType.equals("实验") && experimentCount == -1) {
experimentCount = 0;
}
electedCourse.grade.getTotalGrade();
sum += (int) electedCourse.grade.totalGrade;
if (electedCourse.grade instanceof ExaminationGrade) {
examSum += ((ExaminationGrade) electedCourse.grade).finalGrade;
examNumber++;
} else if (electedCourse.grade instanceof ExperimentGrade) {
examSum += (electedCourse.grade).totalGrade;
} else if (electedCourse.grade instanceof AssessmentGrade) {
examSum += ((AssessmentGrade) electedCourse.grade).finalGrade;
}
courseNumber++;
}
}
if (courseNumber == -1) {
System.out.println(courses.get(courseName).courseName + " has no grades yet");
continue;
}
if (experimentCount != -1) {
experimentAverage = examSum / courseNumber;
System.out.println(courses.get(courseName).courseName + " " + experimentAverage);
continue;
}
int sumAverage = sum / courseNumber;
if (examNumber == -1) {
System.out.println(courses.get(courseName).courseName + " " + sumAverage);
} else {
System.out.println(courses.get(courseName).courseName + " " + sumAverage);
}
}
}
public void showClassInformation (HashMap<String, Class> classes, ArrayList<ElectedCourse> electedCourses) {
Set<String> classNums = classes.keySet();
Set<String> sortSet = new TreeSet<>(String::compareTo);
sortSet.addAll(classNums);
for (String classNum : sortSet) {
int sum = 0, count = -1;
for (ElectedCourse electedCourse : electedCourses) {
if (classes.get(classNum).students.containsKey(electedCourse.student.studentId)) {
if (count == -1) {
count = 0;
}
electedCourse.grade.getTotalGrade();
sum += electedCourse.grade.totalGrade;
count++;
}
}
if (count == -1) {
System.out.println(classes.get(classNum).classNum + " has no grades yet");
continue;
}
int average = sum / count;
System.out.println(classes.get(classNum).classNum + " " + average);
}
}
}
以上代码加了一些把实验跟最终成绩的占比有关,然后再把其他一些类给改一改,具体改法如下在ParseInput类中,新增了对实验课程成绩的处理。添加了ExperimentGrade类,表示实验课程成绩。在inputInformation方法中,根据输入的信息格式,判断是否为实验课程成绩,并进行相应的解析和存储。
Show类中,新增了showCourseInformation方法,用于展示课程的相关信息。根据课程名称对课程进行排序,计算每门课程的平均成绩,并展示出来。
在Course类中,添加了实验课程相关的属性和构造方法。
在Grade抽象类中,新增了实验课程成绩相关的属性和方法。
踩坑心得:
一开始写的时候没有用正则表达式导致代码变得很不条理,然后之后两道题使用了正则表达式,然后就代码条理了很多,还有就是类一开始没分多少,之后就写了不多的类让其他类也是变得不是很条理与麻烦。
类名Class与Java中的关键字冲突,应该避免使用关键字作为类名。
在ParseInput类中,对输入进行解析时的正则表达式匹配存在问题,导致部分输入无法正确解析。
在showCourseInformation方法中,计算实验课的平均分存在问题,应该是实验课的总分除以实验课的数量。
在showClassInformation方法中,变量count的初始值应该是0而不是-1。
在showClassInformation方法中,计算班级平均分时,应该是班级所有学生的总分除以学生数量,而不是选修了课程的学生数量。
在showClassInformation方法中,应该对班级学号进行排序,而不是班级编号。
在Main类中,应该在使用Scanner读取输入之前,先打印提示信息,以便用户知道输入什么样的数据。
主要困难以及改进建议:
主要困难:
- 输入信息的解析和存储:对于复杂的输入信息格式,需要编写正则表达式进行匹配和解析,同时需要合理设计数据结构来存储解析后的信息。
- 成绩计算和展示:根据题目要求,需要对不同类型的课程和成绩进行计算和展示,包括考试课程、考察课程和实验课程的成绩计算和展示,还需要考虑权重和平均成绩的计算方式。
- 错误处理:对于输入信息格式错误或不符合要求的情况,需要进行错误处理并给出相应的提示信息。
- 代码逻辑和结构的设计:需要合理划分代码的模块和功能,确保代码的可读性和可维护性。
期末考试成绩统计的改进建议:
主要目的是管理学生、课程和班级的成绩信息,并进行相应的统计和输出。以下是对该代码的一些建议改进:
优化代码结构:建议将代码按照功能进行模块化,例如创建不同的类文件来管理学生、课程和班级的数据,并使用合适的方法和属性来操作和存储数据。这样可以提高代码的可读性和可维护性。使用面向对象的设计原则:通过使用类、对象、继承和多态等特性,可以更好地组织和管理代码。例如可以创建学生、课程和班级的类,并使用它们的对象来表示相应的数据和行为。使用更具有语义化的变量和方法名:使用更加清晰和易于理解的变量和方法名可以提高代码的可读性和可维护性。例如,可以将变量名改为具有描述性的名字,以更好地反映其用途。同时,建议使用驼峰命名法来命名变量和方法。引入异常处理机制:在代码中引入适当的异常处理机制,以捕获可能出现的错误并采取相应的处理措施。这有助于增强代码的健壮性和容错性。使用更加简洁和高效的数据结构和算法:根据具体的需求,选择合适的数据结构和算法来管理和操作数据。例如,可能可以使用List替代HashMap来存储学生和课程数据,以便更方便地进行排序和遍历。添加注释和文档说明:为代码添加适当的注释和文档说明,以帮助其他开发人员理解代码的逻辑和功能。
总结:
通过这几次测试样例,学会了使用正则表达式来检查输入信息的格式是否符合要求,对于不符合要求的格式给出错误提示。
数据存储和管理:代码使用HashMap和ArrayList等数据结构来存储和管理学生、课程、班级等实体的信息,通过键值对的方式进行数据的存取和查找。
如何设计和实现一个简单的学生成绩管理系统:这段代码展示了如何通过合理的类设计和数据结构选择来实现一个学生成绩管理系统,并通过输入、处理和展示信息的方式完成相应的功能。
正则表达式的应用:代码中使用了正则表达式来检查输入信息的格式是否符合要求,这让我意识到正则表达式在处理字符串匹配和验证方面的重要性。
数据结构的选择和使用:代码中使用了HashMap和ArrayList等数据结构来存储和管理数据,这让我了解了不同数据结构的特点和使用场景,以及如何通过合适的数据结构来提高代码的效率和可读性。
错误处理和异常处理:代码中对输入信息的格式错误进行了处理,并给出相应的错误提示,这让我意识到在实际开发中,对错误和异常的处理是非常重要的,可以提高代码的健壮性和用户体验。
需要进一步学习和研究的地方包括:
设计模式和架构:学习如何使用设计模式和良好的架构来设计和实现更复杂的系统,提高代码的可维护性和可扩展性。
用户界面和交互设计:学习如何设计和实现用户友好的界面和交互,提高系统的易用性和用户体验。
单元测试和自动化测试:了解如何编写有效的测试用例并进行单元测试和自动化测试,提高代码的质量和可靠性。