第三次博客作业
一、 前言
第六次大作业:
第六次大作业是一个全新的系列,课程成绩统计程序,和菜单计价系列相比,在类的设计方面,菜单计价系列我没有用到继承,而课程成绩统计中对于成绩的计算,有考察成绩和考试成绩,这两个类和成绩类都有相似的地方,因此用继承的方式来计算。本次大作业是该系列的第一次作业,所以这次大作业应该算是比较核心的一次作业了,对于类的设计,有类图可以参考,题目中的基本要求也不算很难,基本上没有什么问题。
第七次大作业:
第七次大作业有四道题,但是主要的还是课程成绩统计程序系列,其它三题分别是对hashmap的检索的实现,对hashmap的排序的实现,对多态的掌握。其中对多态的掌握和我们在课堂上写的动物的接口设计似乎差不多,并且这道题还是一道填空题,所以解决起来没有什么难度。而hashmap的题目去网上找找hashmap的用法基本就可以了解并使用,hashmap 上手也不困难,基本就是一遍过,不会卡测试点。对于课程成绩统计程序系列2,本次作业新增了一个实验课和一些实验课的要求,其它内容并无变化。
第八次大作业:
第八次大作业有五道题,第一道是对arraylist的排序,这个要注意的是输出排序是从高到低还是从低到高。第二道题是课程成绩统计程序3,此次系列新增了权重,不同于前两次作业,这个权重是考试课和实验课自带的权重,不是统一的权重,还要注意本次作业输出方式的改变,就是输出课程成绩时不用再输出平时成绩和期末成绩了,只要输出最后的总成绩即可。另外三题似乎是差不多的东西,但是题目内容有点点难懂,搞得我无从下手,其中第四道题涉及到了栈的概念,栈的特性是:后进先出,先进后出,它的本质是用于存储一批相同类型的数据,因此它的底层实现无非两种选择:数组和链表。栈中有三个核心方法:push、pop、peek。push:往栈顶添加元素;pop:从栈顶移除元素;peek:获取栈顶元素,并不做任何添加删除操作。了解了栈的基本特点就可以了。第五道题就是看文字写代码,读懂题目意思好像就感觉没有那么困难了。
二、 设计与分析
- 第六次大作业
7-1 课程成绩统计程序-1
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。考察的总成绩直接等于期末成绩。必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
代码实现:
类的设计为学生类,班级类,课程类,选课类以及成绩类。其中学生类有string类型的学号,string类型的名字,int类型的成绩以及int类型的flag(主要用来判断该名同学是否参加了考试,flag=0是未参加考试,flag=1是参加了考试,后面统一输出的时候就以此作为判断依据,flag=0就输出学号+英文空格+姓名+英文空格+"did not take any exams",flag=1就输出学号+英文空格+姓名+英文空格+总成绩平均分)。还有一个StudentAll类,其主要目的就像它的名字一样,储存所有学生的信息。班级类有string类型的班级号,一个学生数组student,用于储存这个班级的学生信息,其中对于班级是否有成绩,我是增加了一个方法对这个班级的所有学生的flag进行检索,如果有一个学生的flag=1,那么就返回1,如果检索完没有学生的flag=1,就返回0。通过这个方法得到的返回值为1就输出班级号+英文空格+总成绩平均分,如果获得的返回值为0就输出班级名称+英文空格+ "has no grades yet"。课程类有一个string类型的课程名称,一个int类型的课程性质(其中必修课为1,选修课为2),一个int类型的考核方式(其中考试课为1,考查课为2),以及一个int类型的flag(和学生类型的flag是同样的意义和用法,flag=0就输出课程名称+英文空格+"has no grades yet",flag=1就输出课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分),另外类设计中还有一个KechengAll类,这个类也是储存所有课程信息的,其中有一个方法是用来检索新增加的课程是否与已有的课程相同,若相同,则不存入课程数组中。选课类有一个Student类型的学生信息,一个Kecheng类型的课程信息,一个int类型的平时成绩,一个int类型的期末成绩,一个int类型的总成绩。成绩类有一个选课类的数组,成绩类中有两个计算成绩的方法(这个我没有写成继承,感觉这样判断也可以,不用单独开一个继承类),分别是计算考试成绩的方法,和计算考查成绩的方法,这是根据输入的学生考试信息判断的,通过检索该条信息的课程名称,获得该门课程的考核方式,再根据考核方式的不同选择不同的计算成绩的方法。
代码分析:

public class Main{ public static void main(String args[]) { Scanner input=new Scanner(System.in); StudentAll stua=new StudentAll(); KechengAll kec=new KechengAll(); chengji cj=new chengji(); String s=input.nextLine(); String[] str = s.split(" "); int i=0; while(!(str[0].equals("end"))) { if(isNumeric(str[0])) { if(str[0].length()!=8||str[1].length()>10) System.out.println("wrong format"); else if(str.length==4&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==5&&!isNumeric(str[3])&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==4&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)) System.out.println("wrong format"); else if(str.length==5&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)&&(Integer.parseInt(str[4])<0||Integer.parseInt(str[4])>100)) System.out.println("wrong format"); else { stua.addstudent(str[0], str[1]); Kecheng ke=kec.findkecheng(str[2]); if(ke==null) System.out.println(str[2]+" "+"does not exist"); else { if((ke.fangshi==1&&(str.length!=5))||(ke.fangshi==2&&(str.length!=4))) System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); else { int q=cj.findchenji(str[0], str[1], str[2]); if(q==0) { if(ke.fangshi==1) { cj.chengjiA(str[0],str[1], ke, Integer.parseInt(str[3]), Integer.parseInt(str[4])); stua.ifhascj(1); } else if(ke.fangshi==2) { cj.chengjiB(str[0],str[1], ke, Integer.parseInt(str[3])); stua.ifhascj(1); } } } } } } else { if(str.length==2||str.length==3) { if(str[0].length()>10) System.out.println("wrong format"); else { if(str.length==3) { if(str[1].equals("必修")&&str[2].equals("考察")) System.out.println(str[0]+" : course type & access mode mismatch"); else if((str[1].equals("必修")&&str[2].equals("考试"))||(str[1].equals("选修")&&(str[2].equals("考试")||(str[2].equals("考察"))))) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { kec.addKecheng(str[0], str[1], str[2]); } } else System.out.println("wrong format"); } else if(str.length==2) { if(str[1].equals("选修")) System.out.println("wrong format"); else if(str[1].equals("必修")) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { kec.addKecheng(str[0], str[1], "考试"); } } else System.out.println("wrong format"); } } } else System.out.println("wrong format"); } s=input.nextLine(); str = s.split(" "); } stua.stupaixu(cj); kec.paixu(cj); stua.clacjsc(); } }
本次作业中,判断课程信息是否输入正确的方法,我用的不是正则表达式来判断,而是用equals来判断,感觉这样判断起来太麻烦了,别人三个语句就可以搞定的,我还要判断这条课程信息的长度,来判断它是不是可以省略输入考核方式,感觉还是正则表达式简单,用equals不知道写了多少条if语句了,太麻烦了。
- 第七次大作业
课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。实验的总成绩等于课程每次实验成绩的平均分。实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩。实验次数至少4次,不超过9次。实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩
代码实现:
对于新增的课程性质和考核方式,我在课程类中的课程性质里加了一个3指代的是实验课,考核方式也增加了一个3为实验,其中对于实验课程异常信息的判断方式,我选择判断输入的这条信息的字符数组的长度来判断它的实验次数是否符合题目的要求,至少四次,不超过九次。而对于实验课的成绩我是在传入计算成绩的方法前用for循环将实验课的平均成绩算出来后再传的。其它的代码基本不变。
代码分析:

public class Main{ public static void main(String args[]) { Scanner input=new Scanner(System.in); StudentAll stua=new StudentAll(); KechengAll kec=new KechengAll(); chengji cj=new chengji(); String s=input.nextLine(); String[] str = s.split(" "); int i=0; while(!(str[0].equals("end"))) { if(isNumeric(str[0])) { if(str[0].length()!=8||str[1].length()>10) System.out.println("wrong format"); else if(str.length==4&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==5&&!isNumeric(str[3])&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==4&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)) System.out.println("wrong format"); else if(str.length==5&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)&&(Integer.parseInt(str[4])<0||Integer.parseInt(str[4])>100)) System.out.println("wrong format"); else if(str.length>5&&(Integer.parseInt(str[3])<4||Integer.parseInt(str[3])>9)) System.out.println("wrong format"); else if(str.length>5&&!shiyan(str)) System.out.println("wrong format"); else { stua.addstudent(str[0], str[1]); Kecheng ke=kec.findkecheng(str[2]); if(ke==null) { System.out.println(str[2]+" "+"does not exist"); } else { if((ke.fangshi==1&&(str.length!=5))||(ke.fangshi==2&&(str.length!=4))) { System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); } else { int q=cj.findchenji(str[0], str[1], str[2]); if(q==0) { if(ke.fangshi==1) { cj.chengjiA(str[0],str[1], ke, Integer.parseInt(str[3]), Integer.parseInt(str[4])); stua.ifhascj(1); } else if(ke.fangshi==2) { cj.chengjiB(str[0],str[1], ke, Integer.parseInt(str[3])); stua.ifhascj(1); } else if(ke.fangshi==3) { if((str.length-4)!=Integer.parseInt(str[3])) { System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); } else { int grade=0; int numm=str.length; for(int j=4;j<numm;j++) { grade=grade+Integer.parseInt(str[j]); } grade=grade/(numm-4); cj.chengjiC(str[0],str[1], ke,grade); stua.ifhascj(1); } } } } } } } else { if(str.length==2||str.length==3) { if(str[0].length()>10) System.out.println("wrong format"); else { if(str.length==3) { if(str[1].equals("必修")&&str[2].equals("考察")) System.out.println(str[0]+" : course type & access mode mismatch"); else if(str[1].equals("实验")&&!(str[2].equals("实验"))) System.out.println(str[0]+" : course type & access mode mismatch"); else if(!str[1].equals("实验")&&(str[2].equals("实验"))) System.out.println(str[0]+" : course type & access mode mismatch"); else if((str[1].equals("必修")&&str[2].equals("考试"))||(str[1].equals("选修")&&(str[2].equals("考试")||(str[2].equals("考察"))))||(str[1].equals("实验")&&str[2].equals("实验"))) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { kec.addKecheng(str[0], str[1], str[2]); } } else System.out.println("wrong format"); } else if(str.length==2) { if(str[1].equals("选修")) System.out.println("wrong format"); else if(str[1].equals("必修")) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { kec.addKecheng(str[0], str[1], "考试"); } } else System.out.println("wrong format"); } } } else System.out.println("wrong format"); } s=input.nextLine(); str = s.split(" "); } stua.stupaixu(cj); kec.paixu(cj); stua.clacjsc(); } }
对于判断实验课异常信息的处理上,我一开始找不到合适的输出地方,然后在测试用例时结果就和用例输出的不一样,后面找了好久才找到合适的地方输出。还有就是对于异常信息的判断,除了if语句好像找不到其它的办法了,就只有无数个if堆积在一起。
- 第八次大作业
课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重。考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式。实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重。
代码实现:
本次大作业的改变点是权重的输入,对于这个新增的权重,我在课程类中新增了一个int类型的权重(判断考试方式,其中1是考试,2是考查,3是实验),还有一个float数组(这个数组储存的是每项成绩的权重),而与之一起改变的是计算成绩时输入的成绩,这个成绩就是乘了权重后相加的总成绩,其余的没有变化。
代码分析:

public class Main{ public static void main(String args[]) { Scanner input=new Scanner(System.in); StudentAll stua=new StudentAll(); KechengAll kec=new KechengAll(); chengji cj=new chengji(); String s=input.nextLine(); String[] str = s.split(" "); int i=0; while(!(str[0].equals("end"))) { if(isNumeric(str[0])) { if(str[0].length()!=8||str[1].length()>10) System.out.println("wrong format"); else if(str.length==4&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==5&&!isNumeric(str[3])&&!isNumeric(str[3])) System.out.println("wrong format"); else if(str.length==4&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)) System.out.println("wrong format"); else if(str.length==5&&(Integer.parseInt(str[3])<0||Integer.parseInt(str[3])>100)&&(Integer.parseInt(str[4])<0||Integer.parseInt(str[4])>100)) System.out.println("wrong format"); else { stua.addstudent(str[0], str[1]); Kecheng ke=kec.findkecheng(str[2]); if(ke==null) { System.out.println(str[2]+" "+"does not exist"); } else { if((ke.fangshi==1&&(str.length!=5))||(ke.fangshi==2&&(str.length!=4))) { System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); } else { int q=cj.findchenji(str[0], str[1], str[2]); if(q==0) { if(ke.fangshi==1) { float b=Integer.parseInt(str[3])*ke.quan[0]+Integer.parseInt(str[4])*ke.quan[1]; cj.chengjiA(str[0],str[1], ke, Integer.parseInt(str[3]), Integer.parseInt(str[4]),(int)(b)); stua.ifhascj(1); } else if(ke.fangshi==2) { cj.chengjiB(str[0],str[1], ke, Integer.parseInt(str[3])); stua.ifhascj(1); } else if(ke.fangshi==3) { if((str.length-3)!=ke.quanshu) { System.out.println(str[0]+" "+str[1]+" : access mode mismatch"); } else { float grade=0; for(int j=0;j<ke.quanshu;j++) { grade=grade+Integer.parseInt(str[j+3])*ke.quan[j]; } cj.chengjiC(str[0],str[1], ke,(int)(grade)); stua.ifhascj(1); } } } } } } } else { if(str[0].length()>10) System.out.println("wrong format"); else { if(str[1].equals("必修")&&str[2].equals("考察")) System.out.println(str[0]+" : course type & access mode mismatch"); else if(str[1].equals("实验")&&!(str[2].equals("实验"))) System.out.println(str[0]+" : course type & access mode mismatch"); else if(!str[1].equals("实验")&&(str[2].equals("实验"))) System.out.println(str[0]+" : course type & access mode mismatch"); if(str[2].equals("考试")) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { float sum=Float.parseFloat(str[3])+Float.parseFloat(str[4]); if(sum<0.95||sum>1.05) System.out.println(str[0]+" : weight value error"); else { float[] a=new float[2]; a[0]=Float.parseFloat(str[3]); a[1]=Float.parseFloat(str[4]); kec.addKecheng(str[0], str[1], str[2],2,a); } } } else if(str[2].equals("考察")) { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { float[] a=new float[1]; a[0]=1; kec.addKecheng(str[0], str[1], str[2], 1, a); } } else if(str[2].equals("实验")) { if(Integer.parseInt(str[3])<4||Integer.parseInt(str[3])>9) System.out.println("wrong format"); else { Kecheng ke=kec.findkecheng(str[0]); if(ke==null) { int b=Integer.parseInt(str[3]); int l=str.length; if(b!=(l-4)) System.out.println(str[0]+" : number of scores does not match"); else { float total=0; for(int j=0;j<b;j++) { total=total+Float.parseFloat(str[4+j]); } if(total<0.95||total>1.05) System.out.println(str[0]+" : weight value error"); else { float[] a=new float[b]; for(int j=0;j<b;j++) { a[j]=Float.parseFloat(str[4+j]); } kec.addKecheng(str[0], str[1], str[2],b,a); } } } } } else System.out.println("wrong format"); } } s=input.nextLine(); str = s.split(" "); } stua.stupaixu(cj); kec.paixu(cj); stua.clacjsc(); } }
对于此次作业的代码,主要的是精度的判断,选择的是float还是double,我一开始选择的是double数组,然后除了样例其它的测试点都没过,但是后来换成了float数组后测试点就过了。还有这题比较坑的一点是,对于课程成绩的输出,没有了平时成绩和期末成绩,我没注意到这个,导致我15,16测试点一直过不去。
三、 踩坑心得
1.对于正则表达式的判断语句,将常规的筛选规则写好后发现只匹配到一部分数据,剩下的数据匹配不到,原因大多是由于换行导致的(在匹配的时候会按行进行匹配的,因为我们写的规则.中默认是没有\n的,所以到换行时就会以为结束。可以使用替代的方式将换行替换掉,也就是将数据全部都放在同一行,或者在规则中添加换行符即可)。
2.对于float的精度问题,在将字符串转化成float后,要注意它的误差。
四、 主要困难及改进意见
对我而言最大的问题就是一段代码中if-else语句使用太多了,导致代码的可读性太差,过于冗杂,但是又想不到其它简便的方法,每次想出一个新方法要不就报错,要不就输出错误,感觉没有if-else来的快,所以导致我的代码中if-else太多了。
五、 总结
这个系列的大作业难度基本不大,主要的还是收获了一些知识,比如正则表达式的一些常见错误,换行所带来的问题,大小写的问题等等。以及掌握了hashmap的使用,arraylist的使用,收获还是很多的,学习不就是一点一点积累的过程嘛!
浙公网安备 33010602011771号