前言
涉及知识点
1.java的基本语法等;
*如sout语句、循环表达等*
2.java对于类的基本认识.
题量
单个题目
难度
对于要求实现的功能多而杂,放进代码中实现并不容易,尤其当每进行一步就报错QAQ.
设计与分析
源码
import java.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
ParseInput handle=new ParseInput();
while (!line.equals("end")) {
handle.parseInput(line);
line = sc.nextLine();
}
handle.showStudents();
handle.showCourses();
handle.showClasses();
}
}
class ParseInput{
ArrayList<Student> listStudent=new ArrayList<>();
ArrayList<Course> listCourse=new ArrayList<>();
ArrayList<Class> listClass=new ArrayList<>();
ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>();
public void parseInput(String str){
InputMatching mat=new InputMatching();
int flag=mat.matchingInput(str);
switch (flag){
case 0:System.out.println("wrong format");
break;
case 1:courseMessage(str);
break;
case 2:gradeMessage(str);
break;
}
}
public void courseMessage(String str){
String letters[]=str.split(" ");
String courseName=letters[0];
String type=letters[1];
String testType=letters[2];
Course course=new Course(courseName,type,testType);
if(checkCourse(course)){
if(searchCourse(courseName)==null)
listCourse.add(course);
}
}
public void gradeMessage(String str){
String letters[]=str.split(" ");
String stuId= letters[0];//学生学号
String classID= letters[0].substring(0,6);
String name=letters[1];//学生姓名
String courseName=letters[2];//课程名字
//如果该班级第一次出现
if(searchClass(classID)==null){
Class cla=new Class(classID);
listClass.add(cla);
}
Student stu=new Student(classID,stuId,name);
if(!searchStudent(stuId))
listStudent.add(stu);//将学生加入列表中
//课程是否存在
if(searchCourse(courseName)==null){
System.out.println(courseName+" "+"does not exist");
}
//当课程存在时
else if(searchCourse(courseName)!=null){
Course course=searchCourse(courseName);
//考察
if(letters.length==4&&course.testType.equals("考察")){
int finalGrade= Integer.parseInt(letters[3]);
AssessGrade assessGrade=new AssessGrade(finalGrade);
ChooseCourse chooseCourse=new ChooseCourse(course,stu,assessGrade);
if(!searchChooseCourse(name,courseName))
listChooseCourse.add(chooseCourse);
}
//考试
else if(letters.length==5&&course.testType.equals("考试")){
int usualGrade= Integer.parseInt(letters[3]);
int finalGrade= Integer.parseInt(letters[4]);
ExamGrade examGrade=new ExamGrade(usualGrade,finalGrade);
ChooseCourse chooseCourse=new ChooseCourse(course,stu,examGrade);
listChooseCourse.add(chooseCourse);
}
else{
//学号+英文空格+姓名+英文空格+": access mode mismatch"
System.out.println(stuId+" "+name+" "+": access mode mismatch");
}
}
}
public boolean checkCourse(Course course){
int flag1,flag2;
switch(course.getType()){
case "必修":flag1=0;break;
case "选修":flag1=1;break;
default:flag1=-1;break;
}
switch(course.getTestType()){
case "考试":flag2=0;break;
case "考察":flag2=1;break;
default:flag2=-1;break;
}
if(flag1==0&&flag2==0)
return true;
if(flag1==1&&(flag2==0||flag2==1))
return true;
System.out.println(course.getCourseName()+" : course type & access mode mismatch");
return false;
}
public Class searchClass(String classId){
for(Class cls:listClass){
if(cls.getClassId().equals(classId))
return cls;
}
return null;
}
public Course searchCourse(String name){
for(Course course:listCourse){
if(course.getCourseName().equals(name))
return course;
}
return null;
}
public boolean searchStudent(String id){
for(Student stu:listStudent){
if(stu.getId().equals(id))
return true;
}
return false;
}
//查找是否有重复选课成绩
public boolean searchChooseCourse(String stuName,String courseName){
for(ChooseCourse cs:listChooseCourse){
if(cs.student.getStuName().equals(stuName)&&cs.course.getCourseName().equals(courseName))
return true;
}
return false;
}
public void showStudents(){
Collections.sort(listStudent);
for(int i=0;i<listStudent.size();i++){
Student stu=listStudent.get(i);
//从总选课表listChooseCourse中获取该生的选课记录
ArrayList<ChooseCourse> stuCourseSelects=getStudentSelects(stu.getId());
if(stuCourseSelects.size()!=0) {
System.out.println(stu.getId()+" "+stu.getStuName()+" "+getAvgTotalScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(stu.getId()+" "+stu.getStuName()+" "+"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> stuCourseSelects=getCourseSelects(course.getCourseName());
if(stuCourseSelects.size()!=0){
if(course.testType.equals("考试"))
System.out.println(course.getCourseName()+" "+getAvgUsualScore(stuCourseSelects)+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects));
if(course.testType.equals("考察"))
System.out.println(course.getCourseName()+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(course.courseName+" "+"has no grades yet");
}
}
}
public void showClasses(){
Collections.sort(listClass);
for(int i=0;i<listClass.size();i++){
Class cls=listClass.get(i);
ArrayList<ChooseCourse> stuCourseSelects=getClassSelects(cls.getClassId());
if(stuCourseSelects.size()!=0){
System.out.println(cls.getClassId()+" "+getAvgTotalScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(cls.getClassId()+" "+"has no grades yet");
}
}
}
public ArrayList<ChooseCourse> getStudentSelects(String id){
ArrayList<ChooseCourse> choose=new ArrayList<>();
for(ChooseCourse cos:listChooseCourse) {
if (cos.student.getId().equals(id))
choose.add(cos);
}
return choose;
}
public ArrayList<ChooseCourse> getCourseSelects(String courseName){
ArrayList<ChooseCourse> choose=new ArrayList<>();
for(ChooseCourse cos:listChooseCourse) {
if (cos.course.getCourseName().equals(courseName))
choose.add(cos);
}
return choose;
}
public ArrayList<ChooseCourse> getClassSelects(String clsId){
ArrayList<ChooseCourse> choose =new ArrayList<>();
for(ChooseCourse cos:listChooseCourse) {
if (cos.student.getClsId().equals(clsId))
choose.add(cos);
}
return choose;
}
public int getAvgTotalScore(ArrayList<ChooseCourse> cs){
int average=0;
int sum=0;
for(ChooseCourse c:cs){
sum+=c.grade.getTotalGrade();
}
average=sum/cs.size();
return average;
}
public int getAvgUsualScore(ArrayList<ChooseCourse> cs){
int average=0;
int sum=0;
for(ChooseCourse c:cs){
if(c.course.getTestType().equals("考试")){
sum+=c.grade.getUsualGrade();
}
}
average=sum/cs.size();
return average;
}
public int getAvgFinalScore(ArrayList<ChooseCourse> cs){
int average=0;
int sum=0;
for(ChooseCourse c:cs){
sum+=c.grade.finalGrade;
}
average=sum/cs.size();
return average;
}
}
class ChooseCourse{
Course course;
Student student;
Grade grade;
public ChooseCourse(Course course,Student student,Grade grade) {
this.course = course;
this.student=student;
this.grade=grade;
}
}
class Student implements Comparable<Student>{
String stuName;
String id;
String clsId;
public String getId(){
return id;
}
public String getStuName(){
return stuName;
}
public String getClsId(){
return clsId;
}
public Student(String clsId,String id,String stuName) {
this.clsId=clsId;
this.id=id;
this.stuName=stuName;
}
public int compareTo(Student stu){
return getId().compareTo(stu.getId());
}
}
class Course implements Comparable<Course>{
String courseName;
String type;
String testType;
public Course() {
}
public Course(String courseName,String type,String testType) {
this.courseName=courseName;
this.type=type;
this.testType=testType;
}
public String getCourseName(){
return courseName;
}
public String getType(){
return type;
}
public String getTestType(){
return testType;
}
@Override
public int compareTo(Course o) {
Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
return compare.compare(courseName,o.getCourseName());
}
}
class Class implements Comparable<Class>{
String classId;
public Class() {
}
public String getClassId(){
return classId;
}
public Class(String classId) {
this.classId = classId;
}
@Override
public int compareTo(Class o) {
return getClassId().compareTo(o.getClassId());
}
}
abstract class Grade{
int finalGrade;
public Grade() {
}
public abstract int getUsualGrade();
public abstract int getTotalGrade();
}
class ExamGrade extends Grade{
int usualGrade;
public ExamGrade(int usualGrade,int finalGrade) {
this.usualGrade=usualGrade;
this.finalGrade=finalGrade;
}
public int getUsualGrade(){
return usualGrade;
}
public int getFinalGrade(){
return 0;
}
public int getTotalGrade(){
return (int)(usualGrade*0.3+finalGrade*0.7);
}
}
class AssessGrade extends Grade{
public AssessGrade(int finalGrade) {
this.finalGrade=finalGrade;
}
public int getFinalGrade(){
return finalGrade;
}
@Override
public int getUsualGrade() {
return 0;
}
public int getTotalGrade(){
return finalGrade;
}
}
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;
static String scoreInput2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + " " + scoreMatching;
public InputMatching() {
}
public 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);
if (s.matches(scoreInput1) || s.matches(scoreInput2))
return true;
return false;
}
}
踩坑心得
1.功能需求较多,依次实现总是报错,修改完后面的功能又发现之前的功能神奇地无法实现了;
2.类图并不是很好理解,课程与选课,成绩等类经常容易混淆;
3.算法的优化等.
改进建议
1.使用面向对象的设计:考虑将学生、课程和成绩等信息封装成对象,以提高代码的可读性和可维护性。可以创建Student、Course、Grade等类来表示相关的实体,并在类中定义适当的方法和属性来处理相关操作;
2.错误处理和异常处理:在处理输入时,需要考虑错误处理和异常处理。例如,当解析学生信息时,可以使用try-catch块来捕获可能的异常,如数组越界异常等,并进行相应的处理;
3.单一职责原则:在设计和实现功能时,遵循单一职责原则,确保每个类和方法只负责一项具体的功能。这样可以提高代码的可维护性和复用性;
4.代码注释和文档:为代码添加适当的注释和文档,以便其他人理解和维护代码。注释可以解释代码的意图和实现细节,文档可以提供代码的使用方法和示例.
总结
我学到了很多关于代码改进的知识和技巧,我意识到了面向对象的设计和合适的数据结构对于代码的可读性和可维护性的重要性,我还学到了错误处理和异常处理的重要性等;
同时,我也意识到了自身的很多不足,首先,我需要进一步学习和掌握更多的面向对象的设计原则和模式,以便更好地设计和实现代码。其次,我需要深入了解不同的数据结构和算法,并了解它们的优缺点,以便在实际的编程中能够选择合适的数据结构和算法。