一、题目集分析
本次博客将对PTA的第6-8次题目集进行分析,情况如下:
(1)题量分析:
- 第一次练习共计1题(课程成绩统计程序-1)
- 第二次练习共计4题(3道HashMap类型题目的基础操作外加课程成绩统计程序-2)
- 第三次练习共计1题(课程成绩统计程序-3)
从题量而言,数量适中。
(2)知识点分析:
第一次题目集作为课程成绩统计系统的母题给出了该系统的基本框架要求,即相关的类,以及类与类之间的作用关系,像学生类,班级类,成绩类。然后给出相关输入输出的异常情况要求。总体上而言,该题的多种异常情况的处理是一大难点,需要同学们合理运用正则表达式以及先通过解析类进行处理输入的数据,否则的话会导致当输入的异常情况过于复杂时,对应异常情况的输出会出现混论的特点。
第二次题目集考察了HashMap的检索与排序外加一道动物发生器的多态问题,然后就是课程成绩统计系统的加强版,加入了实验课,对实验课的权重要进行分析。
第三次题目集延续题目集二出现了菜单3的题目,此题综合性较强,涉及知识点的灵活运用程度较高。第二三题则涉及数组的遍历与查重和重复数据的删除。紧接一道封装性问题。最后是一道数据类型转换题和日期计算题。题目涉及面较广,内容上综合性不断提升。
二、相关题目源码分析
- 课程成绩统计程序-1
1.题目













2.题目类图

3.题目分析
首先,需要根据所给的类图进行架构,由于题目要求是循环输入,当遇到“end”截至。其中输入的有效数据主要有两种,分别是:(1)课程类信息(2)学生个人的对应课程的成绩信息。我们首先再读入的过程中就需要对这两种不同的信息进行区分,于是直接以字符串的形式读取,再调用slip函数进行分隔,最后通过正则表达式进行处理的方式为最优方式。对于课程信息类,其输入是为了创建一个课表,对应于后续的一系列选择了该课的学生的成绩进行分析。其实此时便可以看出我们需要一个类,其可以架通学生和课程,于是程序之初我们选择先行写入一个选课类,再在其中放入一个课程类的list和一个学生类的list。在此提醒,解析类的作用是及逆行判别的,为了使解析类 看起来更加的清晰明了,我们最好是再写一个方法,其中调用解析类,再根据解析类的返回值走出相应的异常处理。做好这些后,当课程信息符合要求即将其存入列表中,当学生信息符合要求也将其存入列表中。由于选课类很好的组合了课程类和学生类,于是我们选择在选课类中建立相关的方法用于计算学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。再在主方法中调用这些方法进行输出,使得整体的代码看上去更加的简洁明了。
4.源代码
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { int flag1=1;//成绩超出范围的wrongformat检测 //输入的前半段必须建立一张课表作为标准 CourseTable k = new CourseTable(); //后半段输入时必须建立一张多班级的列表 BanjiTable b = new BanjiTable(); //再开始进行输入处理 Scanner input = new Scanner(System.in); String s = input.nextLine(); while (!s.equals("end")) { String[] str = s.split(" "); if (str.length == 3) { if(k.FindCourse(str[0])==null) { //建立课表信息 Course a = new Course(str[0],str[1],str[2]);//创建好单门课程信息后加入大课表 if(str[1].equals("必修")&&str[2].equals("考察")) { a.setFlag(0); System.out.println(str[0]+" : course type & access mode mismatch"); } k.getCourselist().add(a); } } else if (str.length == 4||str.length==5) {//则表示一定是学生信息,于是先对学生信息建立对象 Student stu = new Student(str[0],str[1]); //再为学生的个人课程列表建立信息 if(k.FindCourse(str[2])!=null) { //在班级存在的前提下比对该学生是否已经存在,若存在则无需建立新的学生信息 String coursename = k.FindCourse(str[2]).getCoursename(); String xiu = k.FindCourse(str[2]).getXiu(); String form = k.FindCourse(str[2]).getForm(); Course personbiao = new Course(coursename,xiu,form); stu.getPersoncourse().add(personbiao); if(str.length==4&&xiu.equals("选修")) { int m = Integer.parseInt(str[3]); if(m>100) { flag1=0; } stu.getPersoncourse().get(stu.getPersoncourse().size()-1).setNormalscore(m); stu.getPersoncourse().get(stu.getPersoncourse().size()-1).setFinalscore(m); }else if(str.length==5&&form.equals("考试")) { int m1 = Integer.parseInt(str[3]); int m2 = Integer.parseInt(str[4]); if(m1>100||m2>100) { flag1=0; } stu.getPersoncourse().get(stu.getPersoncourse().size()-1).setNormalscore(m1); stu.getPersoncourse().get(stu.getPersoncourse().size()-1).setFinalscore(m2); }else { if(str.length==4&&form.equals("考察")&&xiu.equals("必修")) { System.out.println(str[2]+" does not exist"); } if((form.equals("考察")&&str.length!=4)||(form.equals("考试")&&str.length!=5)) { System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); } if(str.length==4&&xiu.equals("必修")) { stu.setFlag(0); } } //比对成功说明课程存在 String banhao = str[0].substring(0,6); if(b.FindBanji(banhao)!=null) {//如果比对成功说明班级已经存在,则将学生信息录入已存在的班级 //再在班级中比对该学生是否存在 if(b.FindBanji(banhao).FindStudent(str[0])!=null) { //如果学生也存在还需判断这个学生这门课的成绩是否也存在 //比对个人课表 Student yicunzai = b.FindBanji(banhao).FindStudent(str[0]); //首先判断这个学生的课表里有没有这门课 //有则判断该课成绩是否为0,为0可修改 //有成绩不为0,则执行空方法 //没有,则给该学生的个人列表中加入课程信息 if(yicunzai.FindPersonCourse(str[2])==null) { yicunzai.getPersoncourse().add(personbiao); int weizhi = yicunzai.getPersoncourse().size()-1; if(str.length==4) { int m = Integer.parseInt(str[3]); if(m>100) { flag1=0; } yicunzai.getPersoncourse().get(weizhi).setNormalscore(m); yicunzai.getPersoncourse().get(weizhi).setFinalscore(m); }else if(str.length==5) { int m1 = Integer.parseInt(str[3]); int m2 = Integer.parseInt(str[4]); if(m1>100||m2>100) { flag1=0; } yicunzai.getPersoncourse().get(weizhi).setNormalscore(m1); yicunzai.getPersoncourse().get(weizhi).setFinalscore(m2); } }else {//不为null,说明学生已有这门课 if(!yicunzai.FindCourseFen(str[2])) { //可以添加成绩的前提条件是课程 if(str.length==4) { int m = Integer.parseInt(str[3]); if(m>100) { flag1=0; } yicunzai.FindPersonCourse(str[2]).setNormalscore(m); yicunzai.FindPersonCourse(str[2]).setFinalscore(m); }else if(str.length==5) { int m1 = Integer.parseInt(str[3]); int m2 = Integer.parseInt(str[4]); if(m1>100||m2>100) { flag1=0; } yicunzai.FindPersonCourse(str[2]).setNormalscore(m1); yicunzai.FindPersonCourse(str[2]).setFinalscore(m2); } } } }else { //班级已存在,但是该学生不存在 Banji q = b.FindBanji(banhao); q.getStudentlist().add(stu); } }else {//否则的话新建一个班级,把该行学生信息加入班级中,再加入列表中 Banji a = new Banji(banhao); a.getStudentlist().add(stu); b.getBanjilist().add(a); } }else { System.out.println(str[0]+" "+str[1]+" "+str[2]+" does not exist"); } } s = input.nextLine(); } /***********************************************************************************/ //对应处理问题的输出 if(flag1==0) { System.out.println("wrong format"); } if(flag1==1) { //(1)第一部分的输出对应为以学生为中心的输出 b.getBanjilist().sort(Comparator.naturalOrder()); for (int i=0;i<b.getBanjilist().size(); i++) { b.getBanjilist().get(i).getStudentlist().sort(Comparator.naturalOrder()); //将班级列表中的每一个班级提出对单个班级中的学生按照学号进行排序 //再依照学号顺序输出每位学生的总成绩平均分 for (int j=0;j<b.getBanjilist().get(i).getStudentlist().size();j++) { if(b.getBanjilist().get(i).getStudentlist().get(j).getFlag()==0||b.getBanjilist().get(i).getStudentlist().get(j).PersonAverageScore()==0) { System.out.println(b.getBanjilist().get(i).getStudentlist().get(j).getNum()+" "+b.getBanjilist().get(i).getStudentlist().get(j).getName()+" did not take any exams"); } //20201103 张三 34 String studentnum = b.getBanjilist().get(i).getStudentlist().get(j).getNum(); String studentname = b.getBanjilist().get(i).getStudentlist().get(j).getName() ; int personAver = b.getBanjilist().get(i).getStudentlist().get(j).PersonAverageScore(); if(personAver!=0) { System.out.println(studentnum+" "+studentname+" "+personAver); } } } } //(3)第三部分的输出对应为以课程为中心的输出——输出单门课程的各大平均成绩 k.giveNumToCourse(); k.getCourselist().sort(Comparator.naturalOrder()); if(b.getBanjilist().size()!=0) { b.NormalAverage(k); } for(int i=0;i<k.getCourselist().size();i++) { String kename = k.getCourselist().get(i).getCoursename(); int kenormalfen = k.getCourselist().get(i).getAvernormalscore(); int kefinalfen = k.getCourselist().get(i).getAverfinalscore(); int ketotalfen = k.getCourselist().get(i).getAvertotalscore(); if(kenormalfen==0&&kefinalfen==0&&ketotalfen==0||flag1==0) { if(k.getCourselist().get(i).getFlag()==1||flag1==0) { System.out.println(kename+" has no grades yet"); } }else { if(k.getCourselist().get(i).getForm().equals("考察")) {//这种情况下只需要输出平时成绩的平均分和总平均分即可 System.out.println(kename+" "+kenormalfen+" "+ketotalfen); }else { System.out.println(kename+" "+kenormalfen+" "+kefinalfen+" "+ketotalfen); } } } if(flag1==1) { //(4)第四部分的输出对应为以班级成绩为中心的输出 for (int i=0;i<b.getBanjilist().size(); i++) { b.getBanjilist().get(i).setTotalCourse(k); b.getBanjilist().get(i).setTotalFen(); b.getBanjilist().get(i).setTotalAverFen(); String banname = b.getBanjilist().get(i).getClassnum(); int banfen = b.getBanjilist().get(i).getTotalAverFen(); if(banfen==0) { System.out.println(banname+" has no grades yet"); }else { System.out.println(banname+" "+banfen); } } } input.close(); } } /**********************************************************************/ class Course implements Comparable<Course>{ private int sortNumber; public int getSortNumber() { return sortNumber; } public void setSortNumber(int sortNumber) { this.sortNumber = sortNumber; } private int flag=1;//判断该种课程性质是否存在 public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } private String coursename; private String xiu;//选修必修 private String form;//考试or考察 private int normalscore=0;//平时成绩 private int finalscore=0;//期末成绩,对于考察课程可以令其期末成绩为0 private int totalscore=0;//这门课的总成绩 /*************************************/ //另一部分变量只有在统计课程均分的时候才用的到 private int avernormalscore=0; private int averfinalscore=0; private int avertotalscore=0; public int getAvernormalscore() { return avernormalscore; } public void setAvernormalscore(int avernormalscore) { this.avernormalscore = avernormalscore; } public int getAverfinalscore() { return averfinalscore; } public void setAverfinalscore(int averfinalscore) { this.averfinalscore = averfinalscore; } public int getAvertotalscore() { return avertotalscore; } public void setAvertotalscore(int avertotalscore) { this.avertotalscore = avertotalscore; } public void setNormalscore(int normalscore) { this.normalscore = normalscore; } public void setFinalscore(int finalscore) { this.finalscore = finalscore; } /***********************************/ public String getCoursename() { return coursename; } public int getNormalscore() { return normalscore; } public int getFinalscore() { return finalscore; } public int getTotalscore() { return (int)(this.normalscore*0.3+this.finalscore*0.7); } public String getXiu() { return xiu; } public String getForm() { return form; } //单门课程构造器 Course(String coursename,String xiu,String form){ this.coursename=coursename; this.xiu=xiu; this.form=form; } //一个方法用于course排序 public int compareTo(Course a) { int n1 = this.sortNumber; int n2 = a.getSortNumber(); if (n1>n2) return 1; else if (n1<n2) return -1; return 0; } } /**********************************************************************/ class CourseTable { private ArrayList<Course> courselist = new ArrayList<>(); public ArrayList<Course> getCourselist() { return courselist; } //给一个方法将公共大课表里面的课程信息进行赋值 public void giveNumToCourse() { for(int i=0;i<courselist.size();i++) { if(courselist.get(i).getCoursename().equals("java")) { courselist.get(i).setSortNumber(1); }else if(courselist.get(i).getCoursename().equals("数据结构")) { courselist.get(i).setSortNumber(2); }else if(courselist.get(i).getCoursename().equals("数据库")) { courselist.get(i).setSortNumber(3); }else if(courselist.get(i).getCoursename().equals("形式与政治")) { courselist.get(i).setSortNumber(4); } } } //一个方法返回公共大课表中该课程的信息 public Course FindCourse(String name) { for(int i=0;i<courselist.size();i++) { if(courselist.get(i).getCoursename().equals(name)) { return courselist.get(i); } } return null; } } /*********************************************************************/ class Student implements Comparable<Student>{ private int flag =1;//判断学生是否没参加考试 public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } private String num;//学号 private String name;//姓名 private double persontotalfen=0;//该学生所有课程的总分 private ArrayList<Course> personcourse = new ArrayList<>();//每位学生自己的课程列表 public String getNum() { return num; } public String getName() { return name; } public double getPersontotalfen() { return persontotalfen; } public ArrayList<Course> getPersoncourse() { return personcourse; } //直接根据学号姓名可建立学生信息 Student(String num,String name){ this.num=num; this.name=name; } //一个方法判断个人的该门课程是否有分 public boolean FindCourseFen(String s) { for(int i=0;i<this.personcourse.size();i++) { if(personcourse.get(i).getCoursename().equals(s)&&personcourse.get(i).getFinalscore()!=0) { return true; } } return false; } //一个方法检查个人课程列表中的已有课程 public Course FindPersonCourse(String s) { for(int i=0;i<this.personcourse.size();i++) { if(personcourse.get(i).getCoursename().equals(s)) { return personcourse.get(i); } } return null; } //一个方法计算一个学生所有课程总分下的平均分 public int PersonAverageScore() { int aver=0; double sum=0; for(int i=0;i<personcourse.size();i++) { sum+=personcourse.get(i).getNormalscore()*0.3+personcourse.get(i).getFinalscore()*0.7; } this.persontotalfen=sum; aver+=(int)(sum/personcourse.size()); return aver; } //写好两个学生学号的比较 public int compareTo(Student a) { int n1 = Integer.parseInt(this.num); int n2 = Integer.parseInt(a.getNum()); if (n1>n2) return 1; else if (n1<n2) return -1; return 0; } } /*********************************************************************/ class Banji implements Comparable<Banji>{ private String classnum; private double totalfen; private int cent=0;//记录这个班级总共参与了几门课程 private int TotalAverFen;//班级所有成绩的总均分 private ArrayList<Student> studentlist = new ArrayList<>(); public String getClassnum() { return classnum; } public int getTotalAverFen() { return TotalAverFen; } public ArrayList<Student> getStudentlist() { return studentlist; } // 班级的构造器 Banji(String classnum) { this.classnum = classnum; } //传入学生学号,在班级里面找人,如果找到则返回学生对象 public Student FindStudent(String num) { for(int i=0;i<studentlist.size();i++) { if(studentlist.get(i).getNum().equals(num)) { return studentlist.get(i); } } return null; } //传入大课程列表进行比对,从而计数该班级已经参与的课程 public void setTotalCourse(CourseTable a) { for(int i=0;i<a.getCourselist().size();i++) { for(int j=0;j<studentlist.size();j++) { //再找每个学生的课表进行比对 for(int k=0;k<studentlist.get(j).getPersoncourse().size();k++) { if(studentlist.get(j).getPersoncourse().get(k).getCoursename().equals(a.getCourselist().get(i).getCoursename())) { this.cent++; break; } } } } } //计算班级所有人所有课程的总成绩分 public void setTotalFen() { double sum=0; for(int i=0;i<studentlist.size();i++) { sum+=studentlist.get(i).getPersontotalfen(); } this.totalfen=sum; } //计算该班级所有课程的总成绩的平均分 public void setTotalAverFen() { this.TotalAverFen=(int)(this.totalfen/this.cent); } //写好两个班级号的比较 public int compareTo(Banji a) { int n1 = Integer.parseInt(this.classnum); int n2 = Integer.parseInt(a.getClassnum()); if (n1>n2) return 1; else if (n1<n2) return -1; return 0; } } /*********************************************************************/ class BanjiTable{ private ArrayList<Banji> banjilist = new ArrayList<>(); public ArrayList<Banji> getBanjilist() { return banjilist; } //通过比对班号返回班级对象 public Banji FindBanji(String num) { for(int i=0;i<banjilist.size();i++) { if(banjilist.get(i).getClassnum().equals(num)) { return banjilist.get(i); } } return null; } //一个方法传入课程列表,依照大课表来计算单门课程的(1)平时成绩平均分(2)期末平均分(3)总平均分 public void NormalAverage(CourseTable a) {//直接在方法中将课程列表中的课程的各类平均分全根据数据设置好 //比对课名,提取数据计算 for(int i=0;i<a.getCourselist().size();i++) { int cent=0;//对应每一门课的人数进行计数 int sum1=0;//对应一门课的平时成绩总分 int sum2=0;//对应一门课的期末成绩总分 int sum3=0;//对应一门课的所有人的总分 //先遍历班级列表 for(int j=0;j<banjilist.size();j++) { //再遍历每个班级的学生列表 for(int k=0;k<banjilist.get(j).getStudentlist().size();k++) { //再比对每个学生个人列表中的课程,调出正在统计的课程的平时分 for(int m=0;m<banjilist.get(j).getStudentlist().get(k).getPersoncourse().size();m++) { int n1=banjilist.get(j).getStudentlist().get(k).getPersoncourse().get(m).getNormalscore(); int n2=banjilist.get(j).getStudentlist().get(k).getPersoncourse().get(m).getFinalscore(); int n3=banjilist.get(j).getStudentlist().get(k).getPersoncourse().get(m).getTotalscore(); if(banjilist.get(j).getStudentlist().get(k).getPersoncourse().get(m).getCoursename().equals(a.getCourselist().get(i).getCoursename())&&(n1+n2+n3!=0)) { cent++; sum1+=n1; sum2+=n2; sum3+=n3; } } } } //对课程列表中的课程下的平均分进行设定 if(cent!=0) { a.getCourselist().get(i).setAvernormalscore((int)(sum1/cent)); a.getCourselist().get(i).setAverfinalscore((int)(sum2/cent)); a.getCourselist().get(i).setAvertotalscore((int)(sum3/cent)); } } } }
- 容器-HashMap-排序
1.题目


2.源代码
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { List<Student> banji = new ArrayList<Student>(); Scanner input = new Scanner(System.in); String str = input.nextLine(); while(!str.equals("end")) { String[] student = new String[3]; student=str.split(" "); int score = Integer.parseInt(student[2]); Student a = new Student(student[0],student[1],score); banji.add(a); str = input.nextLine(); } //检索学生信息 Students StudentTable = new Students(banji); StudentTable.ShowSortStudent(); input.close(); } } class Student implements Comparable<Student>{ private String num;//每个学生的标识符,唯一且不相同(key) private String name; private int score; public String getNum() { return num; } public String getName() { return name; } public int getScore() { return score; } Student(String num,String name,int score){ this.num=num; this.name=name; this.score=score; } //实现了从大到小的正向排序 public int compareTo(Student student2) { int s1, s2; s1 = Integer.parseInt(getNum()); s2 = Integer.parseInt(student2.getNum()); if (s1 > s2) return -1; else if (s1 < s2) return 1; return 0; } } class Students{ private List<Student> list; private Map<String,Student> studentMap; Students(List<Student> list){ this.list=list; studentMap=new HashMap(); for(Student a : this.list) { studentMap.put(a.getNum(),a); } } public Student FindStudentByNum(String studentnum) { Student a = studentMap.get(studentnum); return a; } public void ShowSortStudent() { this.list.sort(Comparator.naturalOrder()); for(int i=0;i<list.size();i++) { System.out.println(list.get(i).getNum()+" "+list.get(i).getName()+" "+list.get(i).getScore()); } } }
- 容器-HashMap-检索
1.题目


2.源代码
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { List<Student> banji = new ArrayList<Student>(); Scanner input = new Scanner(System.in); String str = input.nextLine(); while(!str.equals("end")) { String[] student = new String[3]; student=str.split(" "); int score = Integer.parseInt(student[2]); Student a = new Student(student[0],student[1],score); banji.add(a); str = input.nextLine(); } //检索学生信息 Students StudentTable = new Students(banji); String q = input.next(); Student person = StudentTable.FindStudentByNum(q); if(person!=null) { System.out.println(person.getNum()+" "+person.getName()+" "+person.getScore()); }else { System.out.println("The student "+q+" does not exist"); } input.close(); } } class Student{ private String num;//每个学生的标识符,唯一且不相同(key) private String name; private int score; public String getNum() { return num; } public String getName() { return name; } public int getScore() { return score; } Student(String num,String name,int score){ this.num=num; this.name=name; this.score=score; } } class Students{ private List<Student> list; private Map<String,Student> studentMap; Students(List<Student> list){ this.list=list; studentMap=new HashMap(); for(Student a : this.list) { studentMap.put(a.getNum(),a); } } public Student FindStudentByNum(String studentnum) { Student a = studentMap.get(studentnum); return a; } }
- 动物发声模拟器(多态)
1.题目

//动物发生模拟器. 请在下面的【】处添加代码。 public class AnimalShoutTest2 { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } //定义静态方法speak() 【】 } //定义抽象类Animal 【】class Animal{ 【】 } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat 【】{ 【】 【】 } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog 【】{ 【】 【】 } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat 【】{ 【】 【】 }

2.源代码
//动物发生模拟器. 请在下面的【】处添加代码。 public class Main { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } //定义静态方法speak() public static void speak(Animal a) { String s1 = a.getAnimalClass(); String s2 = a.shout(); System.out.println(s1+"的叫声:"+s2); } } //定义抽象类Animal abstract class Animal{ public abstract String getAnimalClass(); public abstract String shout(); } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat extends Animal{ @Override public String getAnimalClass() { String a = "猫"; return a; } @Override public String shout() { String a = "喵喵"; return a; } } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog extends Animal{ @Override public String getAnimalClass() { String a = "狗"; return a; } @Override public String shout() { String a = "汪汪"; return a; } } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat extends Animal{ @Override public String getAnimalClass() { String a = "山羊"; return a; } @Override public String shout() { String a = "咩咩"; return a; } }
- 课程成绩统计程序-2
1.题目








2.题目类图

3.题目分析
4.源代码