大作业分析-3
前言:
本次将会分析第六次大作业,第七次大作业和第八次大作业的部分题目。这三期大作业主要题目从餐馆变成了课程成绩统计程序,难度较之前来说还行,可能是因为我学得更通透了。接下来会主要分析一下三次大作业中的课程成绩统计程序题目。
第六次大作业:
本次大作业作为第一次的课程成绩统计程序题目。初次见这种题目,所以里面判定的问题很大。map,set我初次使用起来还是用的相对满意的,不枉我到处找资料补。本次作业主要是考察课程,学生,成绩,班级的储存计算和排序,主要需要HashSet和HashMap的使用。
第七次大作业:
本次大作业主要难度还是集中在课程统计程序题目。其他题目主要是考察HashMap的使用及多态;而本次课程成绩统计程序题目相较上次题目新增了实验课的选项,及新的计分方式,总体框架并无大改。
第八次大作业:
本次大作业难度照样集中在课程统计程序题目。其他题目主要是考察ArrayList的使用,排序及覆写;而课程成绩统计程序题目则小改了一波,将按固定权值计算成绩改成了权值由用户输入。整体框架小改了一波,难度也提升了一波。
接下来会着重分析几道我认为重点的题目。
设计与分析:
课程成绩统计程序-1:
代码:
import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); int c=0;//判断是否开始输入成绩,0为输入课程,1为输入成绩 int d=0; HashMap<String,Course> allcourse=new HashMap<String,Course>(); HashMap<String,Student> allstudent=new HashMap<String,Student>(); HashSet<Control> selection=new HashSet<Control>(); HashMap<String,Class> allclass=new HashMap<String,Class>(); while(true) { String a=in.nextLine(); if(a.equals("end"))//结束 break; String[] b=a.split(" "); if(b.length!=3&&b.length!=2) c=1; //输入课程 if(c==0) { if(b[0].length()>10)//课程名称超过十个 System.out.println("wrong format"); else if((!b[1].equals("必修")&&!b[1].equals("选修"))) System.out.println("wrong format"); else if(b.length==3&&(!b[2].equals("考试")&&!b[2].equals("考察"))) System.out.println("wrong format"); else if(b.length==3&&b[1].equals("必修")&&b[2].equals("考察"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(allcourse.get(b[0])!=null)//课程重复忽略 continue; else if(b[1].equals("必修"))//必修课 { Course course=new RequiredCourse(b[0]); allcourse.put(b[0],course); } else if(b[1].equals("选修"))//选修课 { Course course=new OptionalCourse(b[0],b[2]); allcourse.put(b[0],course); } else System.out.println("wrong format"); } //输入学生成绩 else { if(b[0].length()!=8||b[1].length()>10)//学号不为八位或者名字大于十 System.out.println("wrong format"); else if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中 { System.out.println(b[2]+" does not exist"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(b.length==4) { if(!b[3].matches("[0-9]||[1-9][0-9]||100"))//超出成绩取值范围 System.out.println("wrong format"); else if(allcourse.get(b[2]).assess().equals("考试"))//只输入了期末成绩,但是是考试课 { System.out.println(b[0]+" "+b[1]+" : access mode mismatch"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2]))) continue; else//输入考察学生成绩 { Achievement achievement=new Examine(Integer.parseInt(b[3])); Control control=new Control(); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); control.addmessage(student,allcourse.get(b[2]),achievement); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } else control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } } else if(b.length==5) { if(!b[3].matches("[0-9]||[1-9][0-9]||100")||!b[4].matches("[0-9]||[1-9][0-9]||100"))//超出成绩取值范围 System.out.println("wrong format"); else if(allcourse.get(b[2]).assess().equals("考察"))//输入了平时和期末成绩,但是是考察课 { System.out.println(b[0]+" "+b[1]+" : access mode mismatch"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2]))) continue; else//输入考试学生成绩 { Achievement achievement=new Text(Integer.parseInt(b[3]),Integer.parseInt(b[4])); Control control=new Control(); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); control.addmessage(student,allcourse.get(b[2]),achievement); } else control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } } else//未输入成绩或其他 { System.out.println("wrong format"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); } } } } List<Student> mapValues = new ArrayList<>(allstudent.values()); Collections.sort(mapValues); for(Student i:mapValues) { int s=0; int n=0; for(Control j:selection) if(i==j.student()) { s+=j.gettotalscore(); n++; } if(n==0) System.out.println(i.number()+" "+i.name()+" did not take any exams"); else { s/=n; System.out.println(i.number()+" "+i.name()+" "+s); } } List<Course> courseValues = new ArrayList<>(allcourse.values()); Collections.sort(courseValues,new SortName()); for(Course i:courseValues) { int u=0;//平时 int f=0;//期末 int s=0;//总 int n=0; for(Control j:selection) if(i==j.course()) { if(i.assess().equals("考试")) u+=j.score().usualperformance(); f+=j.score().finalgrade(); s+=j.gettotalscore(); n++; } if(n==0) System.out.println(i.name()+" has no grades yet"); else { System.out.print(i.name()); if(i.assess().equals("考试")) { u/=n; System.out.print(" "+u); } f/=n; s/=n; System.out.println(" "+f+" "+s); } } for(Class i:allclass.values()) i.gettotalscore(selection); List<Class> classValues = new ArrayList<>(allclass.values()); Collections.sort(classValues); for(Class i:classValues) { if(!i.clascr(selection)) System.out.println(i.num()+" has no grades yet"); else System.out.println(i.num()+" "+i.gettotalscore(selection)); } } public static boolean judge(HashSet<Control> o,Student s,Course c) { for(Control i:o) if(i.student()==s&&i.course()==c) return true; return false; } } //每门课程 abstract class Course { private String name;//课程名称 private String assess; void name(String name) { this.name=name; } void addassess(String b) { assess=b; } String name() { return name; } String assess() { return assess; } } //必修课 class RequiredCourse extends Course { RequiredCourse(String name) { name(name); addassess("考试"); } } //选修课 class OptionalCourse extends Course { OptionalCourse(String name,String b) { name(name); addassess(b); } } //学生 class Student implements Comparable<Student> { private String name;//名字 private String number;//学号 Student(String name,String number) { this.name=name; this.number=number; } String name() { return name; } String number() { return number; } @Override public int compareTo(Student o) { return this.number.compareTo(o.number()); } } //选课中心 class Control { private Student student;//学生信息 private Course course;//课程信息 private Achievement score;//成绩信息 int gettotalscore()//计算该成绩 { return score.gettotalscore(); } Student student() { return this.student; } Course course() { return this.course; } Achievement score() { return score; } void addmessage(Student s,Course c,Achievement a) { this.student=s; this.course=c; this.score=a; } } //成绩 abstract class Achievement { private int finalgrade;//期末成绩 private int usualperformance;//平时成绩 int finalgrade() { return this.finalgrade; } int usualperformance() { return this.usualperformance; } void addfinal(int fina)//添加期末成绩 { this.finalgrade=fina; } void addusual(int usual)//添加平时成绩 { this.usualperformance=usual; } abstract int gettotalscore();//计算总成绩 } //考试成绩 class Text extends Achievement { Text(int usual,int fina)//添加成绩 { this.addfinal(fina); this.addusual(usual); } int gettotalscore() { return (int)(usualperformance()*0.3+finalgrade()*0.7); } } //考察成绩 class Examine extends Achievement { Examine(int finalgrade)//添加成绩 { this.addfinal(finalgrade); } int gettotalscore() { return finalgrade(); } } //班级 class Class implements Comparable<Class> { private String num;//班级序号 private HashSet<Student> students=new HashSet<Student>();//学生 void addnum(String num) { this.num=num; } String num() { return num; } void addstu(Student student) { students.add(student); } boolean clascr(HashSet<Control> o)//判断该班是否有成绩 { int n=0; for(Student a:this.students) for(Control b:o) { if(b.student()==a) n++; } if(n==0) return false; return true; } int gettotalscore(HashSet<Control> o) { int s=0; int n=0; int m=0; for(Student a:this.students) { m=0; n=0; for(Control b:o) { if(b.student()==a) { n+=b.gettotalscore(); m++; } } if(m!=0) n/=m; s+=n; } return s/=students.size(); } @Override public int compareTo(Class o) { return this.num.compareTo(o.num()); } } class SortName implements Comparator<Course> { @Override public int compare(Course o,Course o1) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(o.name(),o1.name()); } }

因为老师在课上讲过相关类图设计,所以相对的,这道题目在设计上并没有让我苦恼太久。主要问题还是在HashMap和HashSet的使用和选择上。
这道题目的整体框架是有问题的,不过这部分我会放在踩坑心得里细讲。先讲一下我写题目时的分析。
在一开始老师便提示我们这道题要用Map来做,但是因为我完全没听过所以完全不能理解为什么,和List和Set的区别在哪里。在查阅部分资料后我理解了。Map和List、Set最大的区别就是它拥有“键值对”(key-value)。键便类似于一个人的身份证号,我知道了你的身份证号,我就能知道你是谁;而值就是这个身份证号对应的一个人的信息。相比起只能使用i或遍历查询内容的List和Set中,Map能使用key来直接查询内容,这便是它的最大优点。所以我们可以用map来储存学生信息(key-学号,value-学生类),课程信息(key-课程名称,value-课程类)及班级信息(key-班级号,value-班级类)。至于选课系统类,我选用了Set(后面也用了List,我感觉没有很大差别?)。
至于后面的按学号课程名称等等排序,我发现无论是Map还是Set都无法直接排序,必须先将他们转化为List才能排序。当然我也不确定是不是我搜索的不全,如果有直接用Map或者Set排序的方法请务必告诉我……
说起来写这个的时候有件好笑的事。我写的比较晚,所以我还没开始写的时候某不愿透露姓名的班长同学已经写完了。然后他跟我吐槽他超过400行就交不上去了,我当时人都傻了。导致后面写到超过400行的时候心里就很悬生怕交不上去,然后发现我的能交欸,乐.jpg。所以这是为什么呢?
课程成绩统计程序-2:
代码:
import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); int d=0; int g=0; HashMap<String,Course> allcourse=new HashMap<String,Course>();//总课程,String存课程名称 HashMap<String,Student> allstudent=new HashMap<String,Student>();//总学生,String存学号 HashSet<Control> selection=new HashSet<Control>();//总选课系统 HashMap<String,Class> allclass=new HashMap<String,Class>();//总班级,String存班号 while(true) { String a=in.nextLine(); if(a.equals("end"))//结束 break; String[] b=a.split(" "); //输入课程信息 if(a.matches("(\\S{1,10})( )(必修|选修|实验)(( )(考试|考察|实验))?")) { if(b.length==2) { if(b[1].equals("选修")||b[1].equals("实验"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(allcourse.get(b[0])!=null)//重复输入忽略本条 continue; else if(b[1].equals("必修"))//正常输入必修课 { Course course=new RequiredCourse(b[0]); allcourse.put(b[0],course); } else//正常输入实验课 { Course course=new Experimentallesson(b[0]); allcourse.put(b[0],course); } } else { if((b[1].equals("必修")&&!b[2].equals("考试"))||(b[1].equals("实验")&&!b[2].equals("实验"))||(b[1].equals("选修")&&b[2].equals("实验")))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(allcourse.get(b[0])!=null)//重复输入课程 continue; else if(b[1].equals("必修"))//正常输入必修课 { Course course=new RequiredCourse(b[0]); allcourse.put(b[0],course); } else if(b[1].equals("选修"))//正常输入选修课 { Course course=new OptionalCourse(b[0],b[2]); allcourse.put(b[0],course); } else//正常输入实验课 { Course course=new Experimentallesson(b[0]); allcourse.put(b[0],course); } } } //输入考试/考察成绩信息 else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )(\\d{1,2}|(100))(( )(\\d{1,2}|(100)))?")) { if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中 { System.out.println(b[2]+" does not exist"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if((allcourse.get(b[2]).assess().equals("考试")&&b.length==4)||(allcourse.get(b[2]).assess().equals("考察")&&b.length==5))//输入的成绩数量和课程的考核方式不匹配 { System.out.println(b[0]+" "+b[1]+" : access mode mismatch"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))//重复的成绩信息 continue; else if(allcourse.get(b[2]).assess().equals("考试"))//输入考试课成绩信息 { Achievement achievement=new Text(Integer.parseInt(b[3]),Integer.parseInt(b[4])); Control control=new Control(); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } else//输入考察课成绩信息 { Achievement achievement=new Examine(Integer.parseInt(b[3])); Control control=new Control(); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } } //输入实验成绩 else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((\\d{1,2}|(100))( ))*(\\d{1,2}|(100)*)")) { if(allcourse.get(b[2])==null)//课程名称不在已输入的课程列表中 { System.out.println(b[2]+" does not exist"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if((b.length-4)!=Integer.parseInt(b[3]))//输入的课程性质和课程的考核方式不匹配 { System.out.println(b[0]+" "+b[1]+" : access mode mismatch"); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2])))//重复的成绩信息 continue; else//输入实验成绩信息 { int[] e=new int[Integer.parseInt(b[3])]; for(int i=0;i<Integer.parseInt(b[3]);i++) e[i]=Integer.parseInt(b[i+4]); Achievement achievement=new Experimental(Integer.parseInt(b[3]),e); Control control=new Control(); if(allstudent.get(b[0])==null) { Student student=new Student(b[1],b[0]); allstudent.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null) { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6),cla); } allclass.get(b[0].substring(0,6)).addstu(student); } control.addmessage(allstudent.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } } else System.out.println("wrong format"); } List<Student> mapValues = new ArrayList<>(allstudent.values()); Collections.sort(mapValues); for(Student i:mapValues) { int s=0; int n=0; for(Control j:selection) if(i==j.student()) { s+=j.gettotalscore(); n++; } if(n==0) System.out.println(i.number()+" "+i.name()+" did not take any exams"); else { s/=n; System.out.println(i.number()+" "+i.name()+" "+s); } } List<Course> courseValues = new ArrayList<>(allcourse.values()); Collections.sort(courseValues,new SortName()); for(Course i:courseValues) { int u=0;//平时 int f=0;//期末 int s=0;//总 int n=0; for(Control j:selection) if(i==j.course()) { if(i.assess().equals("考试")) { u+=j.score().usual(); f+=j.score().fina(); } else if(i.assess().equals("考察")) f+=j.score().fina(); s+=j.score().gettotalscore(); n++; } if(n==0) System.out.println(i.name()+" has no grades yet"); else { System.out.print(i.name()); s/=n; if(i.assess().equals("考试")) { u/=n; f/=n; System.out.println(" "+u+" "+f+" "+s); } else if(i.assess().equals("考察")) { f/=n; System.out.println(" "+f+" "+s); } else System.out.println(" "+s); } } // for(Class i:allclass.values()) // i.gettotalscore(selection); List<Class> classValues = new ArrayList<>(allclass.values()); Collections.sort(classValues); for(Class i:classValues) { if(!i.clascr(selection)) System.out.println(i.num()+" has no grades yet"); else System.out.println(i.num()+" "+i.gettotalscore(selection)); } } public static boolean judge(HashSet<Control> o,Student s,Course c) { for(Control i:o) if(i.student()==s&&i.course()==c) return true; return false; } } //每门课程 abstract class Course { private String name;//课程名称 private String assess; void name(String name) { this.name=name; } void addassess(String b) { assess=b; } String name() { return name; } String assess() { return assess; } } //必修课 class RequiredCourse extends Course { RequiredCourse(String name) { name(name); addassess("考试"); } } //选修课 class OptionalCourse extends Course { OptionalCourse(String name,String b) { name(name); addassess(b); } } //实验课 class Experimentallesson extends Course { Experimentallesson(String name) { name(name); addassess("实验"); } } //学生 class Student implements Comparable<Student> { private String name;//名字 private String number;//学号 Student(String name,String number) { this.name=name; this.number=number; } String name() { return name; } String number() { return number; } @Override public int compareTo(Student o) { return this.number.compareTo(o.number()); } } //选课中心 class Control { private Student student;//学生信息 private Course course;//课程信息 private Achievement score;//成绩信息 int gettotalscore()//计算该成绩 { return score.gettotalscore(); } Student student() { return this.student; } Course course() { return this.course; } Achievement score() { return score; } void addmessage(Student s,Course c,Achievement a) { this.student=s; this.course=c; this.score=a; } } //成绩 abstract class Achievement { private int finalgrade;//期末成绩 private int usualperformance;//平时成绩 void addfinal(int fina) { this.finalgrade=fina; } void addusual(int usual) { this.usualperformance=usual; } int fina() { return this.finalgrade; } int usual() { return this.usualperformance; } abstract int gettotalscore();//计算总成绩 } //考试成绩 class Text extends Achievement { Text(int usual,int fina)//添加成绩 { addfinal(fina); addusual(usual); } int gettotalscore() { return (int)(usual()*0.3+fina()*0.7); } } //考察成绩 class Examine extends Achievement { Examine(int finalgrade)//添加成绩 { addfinal(finalgrade); } int gettotalscore() { return fina(); } } class Experimental extends Achievement { private int time;//实验次数 private int[] score;//每次实验成绩 Experimental(int time,int[] score) { this.score=new int[time]; this.time=time; this.score=score; } @Override int gettotalscore() { int s=0; for(int i=0;i<this.time;i++) s+=score[i]; return s/time; } } //班级 class Class implements Comparable<Class> { private String num;//班级序号 private HashSet<Student> students=new HashSet<Student>();//学生 void addnum(String num) { this.num=num; } String num() { return num; } void addstu(Student student) { students.add(student); } boolean clascr(HashSet<Control> o)//判断该班是否有成绩 { int n=0; for(Student a:this.students) for(Control b:o) { if(b.student()==a) n++; } if(n==0) return false; return true; } int gettotalscore(HashSet<Control> o) { int s=0; int n=0; int m=0; int p=0; for(Student a:this.students) { m=0; n=0; for(Control b:o) { if(b.student()==a) { n+=b.gettotalscore(); m++; } } if(m!=0) { n/=m; p++; } s+=n; } if(p!=0) return s/=p; return 0; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num()); } } class SortName implements Comparator<Course> { @Override public int compare(Course o,Course o1) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(o.name(),o1.name()); } }

首先要感谢某不愿透露姓名的班长同学很努力的把我捞到了满分。他指出了我没注意到的错误并教我怎么改了,非常感谢能带懂憨憨。
说起来这个代码复杂度是不是低的吓人了软件真的没问题吗……我这么厉害我怎么不知道。
总之这道题目仅仅是相较上次增加了实验课,整体类图倒是无需大改,省了我很多时间。主要的问题在于我的判定情况出了很大问题导致样例过不去,同时也让我一下子意识到了我上道题目为什么没有满分。这点当然后面再说。
其实这道题要讲设计也没什么好讲的,和上道题目差不多。所以我们先跳下一道题。
(这道题某人依旧超400行交不上去,乐,这是被针对了吗)
课程成绩统计程序-3:
代码:
import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); HashMap<String,Course> allcourse=new HashMap<String,Course>(); HashMap<String,Student> allstu=new HashMap<String,Student>(); ArrayList<Control> selection=new ArrayList<Control>(); HashMap<String,Class> allclass=new HashMap<String,Class>(); while(true) { String a=in.nextLine(); if(a.equals("end")) break; String[] b=a.split(" "); //输入课程信息 if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))"))//输入考试课 { if(b[1].equals("实验")||!b[2].equals("考试"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if((Float.parseFloat(b[3])+Float.parseFloat(b[4]))>1.01||(Float.parseFloat(b[3])+Float.parseFloat(b[4]))<0.99)//分项成绩权重值的总和不等于1 System.out.println(b[0]+" : weight value error"); else if(allcourse.get(b[0])!=null)//重复课程信息 continue; else if(b[1].equals("必修"))//正常输入必修课 { float[] c=new float[2]; for(int i=0;i<2;i++) c[i]=Float.parseFloat(b[i+3]); Course course=new RequiredCourse(b[0],c); allcourse.put(b[0],course); } else//正常输入选修课 { float[] c=new float[2]; for(int i=0;i<2;i++) c[i]=Float.parseFloat(b[i+3]); Course course=new OptionalCourse(b[0],c); allcourse.put(b[0],course); } } else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)"))//输入考察课 { if(!b[1].equals("选修")||!b[2].equals("考察"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(allcourse.get(b[0])!=null)//重复课程信息 continue; else//正常输入选修课 { Course course=new OptionalCourse(b[0]); allcourse.put(b[0],course); } } else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(考试|考察|实验)( )([4-9])(( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])))*"))//输入实验课 { float d=0; float[] c=new float[b.length-4]; for(int i=0;i<(b.length-4);i++) { c[i]=Float.parseFloat(b[i+4]); d+=c[i]; } if(!b[1].equals("实验")||!b[2].equals("实验"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(Integer.parseInt(b[3])!=(b.length-4))//分项成绩数量值和分项成绩权重的个数不匹配 System.out.println(b[0]+" : number of scores does not match"); else if(d>1.01||d<0.99)//分项成绩权重值的总和不等于1 System.out.println(b[0]+" : weight value error"); else if(allcourse.get(b[0])!=null)//重复课程信息 continue; else//正常输入实验课 { Course course=new Experimentallesson(b[0],c); allcourse.put(b[0],course); } } else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]))"))//输入考试课 { if(!b[1].equals("必修"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if((Float.parseFloat(b[3])+Float.parseFloat(b[2]))>1.01||(Float.parseFloat(b[3])+Float.parseFloat(b[2]))<0.99)//分项成绩权重值的总和不等于1 System.out.println(b[0]+" : weight value error"); else if(allcourse.get(b[0])!=null)//重复课程信息 continue; else//正常输入必修课 { float[] c=new float[2]; for(int i=0;i<2;i++) c[i]=Float.parseFloat(b[i+2]); Course course=new RequiredCourse(b[0],c); allcourse.put(b[0],course); } } else if(a.matches("(\\S{1,10})( )(必修|选修|实验)( )([4-9])(( )(([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])))*"))//输入实验课 { float d=0; float[] c=new float[b.length-3]; for(int i=0;i<(b.length-3);i++) { c[i]=Float.parseFloat(b[i+3]); d+=c[i]; } if(!b[1].equals("实验"))//输入的课程性质和课程的考核方式不匹配 System.out.println(b[0]+" : course type & access mode mismatch"); else if(Integer.parseInt(b[2])!=(b.length-3))//分项成绩数量值和分项成绩权重的个数不匹配 System.out.println(b[0]+" : number of scores does not match"); else if(d>1.01||d<0.99)//分项成绩权重值的总和不等于1 System.out.println(b[0]+" : weight value error"); else if(allcourse.get(b[0])!=null)//重复课程信息 continue; else//正常输入实验课 { Course course=new Experimentallesson(b[0],c); allcourse.put(b[0],course); } } //输入成绩信息 else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})(( )(\\d{1,2}|(100)))*")) { if(allcourse.get(b[2])==null)//课程不存在 { System.out.println(b[2]+" does not exist"); if(allstu.get(b[0])==null)//学生不存在 { Student student=new Student(b[1],b[0]); allstu.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null)//班级不存在 { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6), cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if((allcourse.get(b[2]).assess().equals("考试")&&b.length!=5)||(allcourse.get(b[2]).assess().equals("考察")&&b.length!=3)||(allcourse.get(b[2]).assess().equals("实验")&&b.length!=(allcourse.get(b[2]).weight().length+3)))//输入的成绩数量和课程的考核方式不匹配 { System.out.println(b[0]+" "+b[1]+" : access mode mismatch"); if(allstu.get(b[0])==null)//学生不存在 { Student student=new Student(b[1],b[0]); allstu.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null)//班级不存在 { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6), cla); } allclass.get(b[0].substring(0,6)).addstu(student); } } else if(judge(allstu.get(b[0]),allcourse.get(b[2]),selection))//重复输入学生信息 continue; else//输入成绩信息 { if(allstu.get(b[0])==null)//学生不存在 { Student student=new Student(b[1],b[0]); allstu.put(b[0],student); if(allclass.get(b[0].substring(0,6))==null)//班级不存在 { Class cla=new Class(); cla.addnum(b[0].substring(0,6)); allclass.put(b[0].substring(0,6), cla); } allclass.get(b[0].substring(0,6)).addstu(student); } ArrayList<Eachscore> s=new ArrayList<Eachscore>(); for(int i=3;i<b.length;i++) { Eachscore e=new Eachscore(); e.add(Integer.parseInt(b[i]),allcourse.get(b[2]).weight()[i-3]); s.add(e); } Achievement achievement=new Achievement(); achievement.add(s); Control control=new Control(); control.addmessage(allstu.get(b[0]),allcourse.get(b[2]),achievement); selection.add(control); } } else//格式错误 System.out.println("wrong format"); } List<Student> mapValues = new ArrayList<>(allstu.values()); Collections.sort(mapValues); for(Student i:mapValues) { int s=0; int n=0; for(Control j:selection) if(i==j.student()) { s+=j.gettotalscore(); n++; } if(n==0) System.out.println(i.number()+" "+i.name()+" did not take any exams"); else { s/=n; System.out.println(i.number()+" "+i.name()+" "+s); } } List<Course> courseValues = new ArrayList<>(allcourse.values()); Collections.sort(courseValues,new SortName()); for(Course i:courseValues) { int m=0;//计算成绩 int n=0;//计算成绩份数 for(Control j:selection) if(j.course()==i) { m+=j.gettotalscore(); n++; } if(n==0) System.out.println(i.name()+" has no grades yet"); else { m/=n; System.out.println(i.name()+" "+m); } } List<Class> classValues = new ArrayList<>(allclass.values()); Collections.sort(classValues); for(Class i:classValues) { if(!i.clascr(selection))//该班级没有成绩 System.out.println(i.num()+" has no grades yet"); else System.out.println(i.num()+" "+i.gettotalscore(selection)); } } public static boolean judge(Student s,Course c,ArrayList<Control> o) { for(Control i:o) if(i.student()==s&&i.course()==c) return true; return false; } } //每门课程 abstract class Course { private float[] weight;//权重 private String name;//课程名称 private String assess;//考核方式 void name(String name) { this.name=name; } void addassess(String b) { assess=b; } void addweight(float[] w) { this.weight=w; } String name() { return name; } String assess() { return assess; } float[] weight() { return this.weight; } } //必修课 class RequiredCourse extends Course { RequiredCourse(String name,float[] w) { name(name); addassess("考试"); addweight(w); } } //选修课 class OptionalCourse extends Course { OptionalCourse(String name,float[] w)//考试课输入 { name(name); addassess("考试"); addweight(w); } OptionalCourse(String name)//考察课输入 { name(name); addassess("考察"); float[] w=new float[1]; w[0]=1; addweight(w); } } //实验课 class Experimentallesson extends Course { Experimentallesson(String name,float[] w) { name(name); addassess("实验"); addweight(w); } } //学生 class Student implements Comparable<Student> { private String name;//名字 private String number;//学号 Student(String name,String number) { this.name=name; this.number=number; } String name() { return name; } String number() { return number; } @Override public int compareTo(Student o) { return this.number.compareTo(o.number()); } } //选课中心 class Control { private Student student;//学生信息 private Course course;//课程信息 private Achievement score;//成绩信息 int gettotalscore()//计算该成绩 { return score.gettotalscore(); } Student student() { return this.student; } Course course() { return this.course; } Achievement score() { return score; } void addmessage(Student s,Course c,Achievement a) { this.student=s; this.course=c; this.score=a; } } //课程成绩类 class Achievement { private ArrayList<Eachscore> allscore=new ArrayList<Eachscore>(); int gettotalscore() { float n=0; for(Eachscore i:allscore) n+=i.score()*i.weight(); return (int)n; } void add(ArrayList<Eachscore> e) { this.allscore=e; } } //分项成绩类 class Eachscore { private int score;//成绩分值 private float weight;//权重 int score() { return score; } float weight() { return weight; } void add(int score,float weight) { this.score=score; this.weight=weight; } } //班级 class Class implements Comparable<Class> { private String num;//班级序号 private HashSet<Student> students=new HashSet<Student>();//学生 void addnum(String num) { this.num=num; } String num() { return num; } void addstu(Student student) { students.add(student); } boolean clascr(ArrayList<Control> o)//判断该班是否有成绩 { for(Student a:this.students) for(Control b:o) if(b.student()==a) return true; return false; } int gettotalscore(ArrayList<Control> o) { int s=0; int n=0; int m=0; int p=0; for(Student a:this.students) { m=0; n=0; for(Control b:o) if(b.student()==a) { n+=b.gettotalscore(); m++; } if(m!=0) { n/=m; p++; } s+=n; } return s/p; } @Override public int compareTo(Class o) { return this.num.compareTo(o.num()); } } class SortName implements Comparator<Course> { @Override public int compare(Course o,Course o1) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(o.name(),o1.name()); } }

本道题目从要求上就有大改。权值由固定变成了用户输入,同时将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
实不相瞒,我一开始看晕了。
其实本道题主要还是要在更改上面类的同时,在课程中增加权值的属性。还有,输入判断条件要大改。所以其实我也不是很明白是不是因为我考虑不全面,在输入判定就错了才导致几个测试点一直没过……
踩坑心得:
课程成绩统计程序-1:
1.最大的问题就是输入判定问题,我一开始用的是沿用菜单题目的想法,用if-else来从左往右输入判定情况,但是知道做课程成绩统计程序2才意识到,格式错误的判定情况是最优先级,也就是说无论如何都要先判定格式是否错误。那么原先的判定规则我全部都要大改了。后来经班长提点才明白可以用正则表达式来写,才真正意识到这个的用处有多么的大。(之前都只用来判定是不是数字或者整数……是我大材小用了……)
等等,我之前餐馆题目一直没有满分不会也是因为这个吧。
2.课程名称包含中文字符,没办法和英文字符一起按名字来排序。所以这个我去网上找了下方法,这么写就解决了。


3.这其实主要是我眼瞎的问题:我把班级按班级号排序看成了按班级平均分排序,所以我说为什么做起来那么困难(因为按平均分排序我要重新写算分方法……)直到我开始测测试点才知道我是多么的眼瞎……
课程成绩统计程序-2:
- 如上所述的输入判定问题,用正则表达式后方便了许多。
- 关于班级成绩计算。我之前问过某不愿透露姓名的班长,班级成绩的输入要不要算上没有成绩的人,他十分确定地告诉我要算。然后我提交后就错一个测试点。没办法了我就试下不算呗,结果过了……然后这个憨憨告诉我他记错了……
课程成绩统计程序-3:
1.这里绝对是题目的问题……题目描述和样例输入不符。在一开始,题目的描述是:

然后我这么输入后,提交上去测试点除了那几个样例全错。我一想不对劲啊,拿着上次的检查发现只需要输出课程名称+英文空格+“does not exist”就够了。
……等一下,我发现我第一题也是这个输出(第二题输出被带着改回来了),不会吧……我的第一题……
2.权值属性的字符类型。我一开始比较憨,脑子一抽就写了int上去,后面输出才感觉不对劲……然后改成了double类型,样例成功过了但是其他测试点是没过。然后某看着我受苦的班长才提醒我这道题一定要用float,并且判定权值之和为1不能用“==1”,而是得用“>0.99 && <1.01”,这题目……哈哈……
3.至于测试点14我是真找不到错哪里了……并且我还多错了一个测试点16……为什么……
主要困难及改进建议:
- 眼瞎。眼瞎这问题还真不好治……得多读几遍题目了。
- 对题目的分析理解还不够深刻。例如我一直没有意识到格式错误是最优先判定级……
- 对语法等方法运用不熟练。Matches完全没想到能这么用就算了,还不会用……再次感谢愿意不厌其烦教会我这个憨憨的班长。非常感谢。
- 坑,很坑。不过也有我题目做的不够多的原因吧。我是完全没想到会有精度这种问题。仔细想想开学的java题目有一道就是和精度相关,但是我完全没把它放在心上。太坑了……估计以后也会出很多这种题目,我要多注意注意。
- 猜测试点……真的很麻烦……而且很多测试点是从一开始程序结构上就出了问题,如果顺着原结构想很难想出到底问题在哪里。在没有人指点的情况下真的很难靠自己拿到满分。当然那几个一开始就满分了的佬不算,他们是真的天才,而我是真的纯菜……
6.多预习,多复习,多花时间在了解语法上面,争取不要在用的时候不会,甚至完全不知道。
总结:
- 教师与课程方面:老师这次愿意讲解一下这道题真是太好了……节约了我大量的时间以及指点了正确的方向。要我自己写肯定是差的离谱……万分感谢。但是讲javafx的时候讲的有点快qwq我还在琢磨怎么装软件他就开始讲起来了,没软件干巴巴地听也很难记住,导致后面的课都基本跟不上,只能自学,而且没有题目练习,实在是有点容易忘了……
- 作业方面:愿意出点map和list题目是极好的……我太需要这种相关练习来帮助我记忆这些方法用法了。
- 实验方面:有点难但确实很有用。但是靠自己也不知道成绩,不知道自己做的如何,也不知道有些问题该怎么解决……有点孤立无援的感觉。
- 课上方面:希望能边讲边让我们尝试怎么做。毕竟这东西还挺难记住的……

浙公网安备 33010602011771号