一、前言
本次题目集横跨时间较长,也是本课程的最后一次总结了,回首看第一次OO总结,真的感觉今时不同往日了,不仅仅是在能力上的提升,在各方各面上无疑都觉得已经成长了许多(变成了puls版小菜鸡)。
题目集七
本次题目集是菜单3的与菜单4不同迭代分支,是对于菜单3的另一个迭代方向,只要考察了类的设计、代码的逻辑、正则表达式的判断等内容,难度不大,本次题目集仅1道题。
题目集八
从本次题目集之后菜单类的题目迭代就告一段落了,开始了课程成绩统计的迭代,本次题量也是只有一道,是基础的题目分析以及类设计,相对的时间也不长,给了四天左右的期限。
题目集九
本次题目集是拓展题目,只有一道,统计程序中关键词出现的次数,难点在于限制行数以及单一职责原则的要求,题目不难。
题目集十
本次题目集共四道题目,考察课程成绩统计程序的第一次迭代、HashMap的运用以及多态,花费时间较多的还是课程2,相较于其他的题目还是体量更大一些。
题目集十一
本次题目集是最后一次题目集,五道题,涵盖课程成绩程序的第二次迭代、对于ArrayList的考察、各种排序的设计以及接口与覆盖。
二、设计与分析
1. 课程成绩统计程序
--题目集8-1、题目集10-3、题目集11-2
在菜单之后,我们开始了课程成绩统计程序的迭代:
(1)8-1
对于题目分析如下:
分析:在本次迭代开始的时候,吸取菜单程序的教训,为了使程序更加健壮,本次编写我花费了更多时间在类设计上,分析题目解析主干,抽离出各个类,满足单一职责原则,这也使在之后的两次迭代中并没有像上次的菜单一样大量重写,提高了效率。
<1> 最开始的时候由于题目还没有出来,我是根据老师所给的word版题目进行设计,这是当时设计的草稿(不知道为什么没想起来用类图)
其实这个图也就包含了我对题目的分析,以及他们是之间是什么什么关系之类的。后来在pta题目集出来后我也是直接就按照这个设计来写的代码,只大概浏览了一遍题目,感觉没什么差别就开始写了,后来在写完最初版本后,开始按照所给的样例进行测试时,才发现了不对(悲),因为我漏了pta题目中给出的新的异常情况,最开始老师所给的版本做的分析如下
是只有三个的,漏了两个(pta与word有一点不一样),然后我就愣是看不懂样例,在那里找了半天都不知道那个结果是怎么出来的(pta字密密麻麻的,真的没找到),然后跑去问了同学,他就截图给我看,才发现自己漏了(有被自己蠢到)。
这是修改后的分析
<2> 后来再对自己的代码按着测试样例各种修改,还发现自己的类设计有多余的部分,这里是因为题目理解错意思所导致,最开始的类图如下
下面这个是最后的类图
可以看出我最开始的时候是多设计了CourseClassGrades类,按照我最开始的设想,是将每个班级的每个课程成绩先分别储存起来,最后输出的时候再计算,这样的话设计就会出现CourseClassGrades类,如下:
计算课程平均分的时候是一个个调用每个班级中每个课程的成绩相加算平均分,后来在和同学讨论后,发现并不是这样计算的,应该是每个同学的每个成绩相加再除以成绩个数,如下
那么这么计算的话就是不需要CourseClassGrades,直接在班级类中加入学生列表就可以了。
<3> 在本次编写中,我认为比较难以把控的还是正则表达式,因为他可以选择的范围太过于广泛,有的时候可能都意识不到自己原来是这里错了,像我最开始写的
1 Pattern p_Course = Pattern.compile("(\\S+) (\\S{2}) (\\S{2})"); 2 Pattern p_ExCour = Pattern.compile("(\\d{8}) (\\S{0,10}) (\\S{0,10}) (\\d+) (\\d+)"); 3 Pattern p_ExineCour = Pattern.compile("(\\d{8}) (\\S{0,10}) (\\S{0,10}) (\\d+)"); 4 Pattern p_end = Pattern.compile("end");
感觉好像也符合判定,但就是不够精准,后面不断地改正、与同学讨论,才得到了最终版
1 Pattern pCour = Pattern.compile("(\\S{1,10}) (必修|选修) (考试|考察)"); 2 Pattern pEx = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)"); 3 Pattern pExine = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100)"); 4 Pattern pend = Pattern.compile("end");
就两个一对比,真的差的蛮大的,一看就知道最后的明显更好。
最后代码如下:
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 10 int k; 11 CoSe coSe; 12 Course cour; 13 Student stu; 14 AbGrad grad; 15 ExGrad ex; 16 ExineGrad exine; 17 CourStuGrad CSGrad; 18 19 ArrayList<Course> CourL = new ArrayList<>(); 20 ArrayList<Student> Stus = new ArrayList<>(); 21 ArrayList<Classes> ClassL = new ArrayList<>(); 22 ArrayList<CoSe> coSeL = new ArrayList<>(); 23 24 String s,z = null,z4,z5; 25 Pattern pCour = Pattern.compile("(\\S{1,10}) (必修|选修) (考试|考察)"); 26 Pattern pEx = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)"); 27 Pattern pExine = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100)"); 28 Pattern pend = Pattern.compile("end"); 29 Matcher mCour,mEx,mExine,mend; 30 31 //输入 32 while(true){ 33 s = in.nextLine(); 34 mCour = pCour.matcher(s); 35 mEx = pEx.matcher(s); 36 mExine = pExine.matcher(s); 37 mend = pend.matcher(s); 38 39 coSe = new CoSe(); 40 stu = coSe.getStu(); 41 42 if(mend.matches()){ 43 break; 44 } 45 46 else if(mCour.matches()){//课程信息 47 //加入所有课程的列表 48 z = mCour.group(1); 49 z4 = mCour.group(2); 50 z5 = mCour.group(3); 51 cour = new Course(z,z4,z5); 52 if(cour.isNa(z4,z5)){ 53 if(seaC(z,CourL) == -1) 54 CourL.add(cour); 55 } 56 else{ 57 pr(cour.getName() + " : course type & access mode mismatch"); 58 } 59 } 60 else if(mEx.matches() || mExine.matches()){//考试的课程成绩 //考察的课程成绩 61 //学号的字符串转数字数组 62 int a = 0,b = 0,flag = 0; 63 boolean fa = mEx.matches(); 64 boolean fb = mExine.matches(); 65 if(fa){ 66 stu.StrToInt(mEx.group(1));//学号 67 stu.setName(mEx.group(2));//姓名 68 69 z = mEx.group(3); 70 a = Integer.parseInt(mEx.group(4)); 71 b = Integer.parseInt(mEx.group(5)); 72 } 73 if(fb){ 74 stu.StrToInt(mExine.group(1));//学号 75 stu.setName(mExine.group(2));//姓名 76 77 z = mExine.group(3); 78 a = Integer.parseInt(mExine.group(4)); 79 } 80 81 k = seaC(z,CourL); 82 83 //异常情况:课程名称不在已输入的课程列表中 84 if(k == -1){ 85 pr(z +" does not exist"); 86 } 87 else { 88 //如果没有重复的课程成绩信息 89 if(seaTT(stu.getNum(), stu.getName(),z,coSeL) == -1){ 90 cour = CourL.get(k); 91 coSe.setCour(cour);//根据课程名字加入 92 93 //异常情况:输入的成绩数量和课程的考核方式不匹配 94 if(fa){ 95 if(!cour.MathAss("考试")) {//找到课程名字,看是否为考试 96 flag = 1; 97 } 98 else{ 99 coSe.setGrad(new ExGrad(a,b));//把课程成绩输入找到对应课程 100 } 101 } 102 if(fb){ 103 if(!cour.MathAss("考察") || !cour.MathNa("选修")) {//找到课程名字,看是否为考察 104 flag = 1; 105 } 106 else{ 107 coSe.setGrad(new ExineGrad(a));//把课程成绩输入找到对应课程 108 } 109 } 110 if(flag == 1){ 111 prNum(stu.getNum()); 112 pr(" " + stu.getName() +" : access mode mismatch"); 113 } 114 } 115 } 116 coSe.setStu(stu); 117 coSeL.add(coSe); 118 } 119 //格式错误以及其他信息异常如成绩超出范围 120 else { 121 prW(); 122 } 123 } 124 125 for (CoSe sl : coSeL) {//对于每一组数据分别储存 126 //对于这个学生开始操作 127 int[] num = sl.getStu().getNum(); 128 cour = sl.getCo(); 129 stu = sl.getStu(); 130 grad = sl.getGrad(); 131 k = seaS(num,Stus); 132 String str = cour.getAss(); 133 134 //存入Student,Stus 135 if (k == -1) {//学生不存在 136 Stus.add(stu); 137 k = seaS(num,Stus); 138 } 139 140 if(str != null && grad != null){ 141 //计算学生成绩,存入学生数据 142 if (str.equals("考试")) { 143 //计算总成绩 144 ex = (ExGrad) grad; 145 ex.CalGrad(); 146 //找到这个学生,赋给成绩 147 Stus.get(k).AGrad(cour.getName(), ex); 148 } 149 if (str.equals("考察")) { 150 exine = (ExineGrad) grad; 151 exine.CalGrad(); 152 //找到这个学生,赋给成绩 153 Stus.get(k).AGrad(cour.getName(), exine); 154 } 155 } 156 157 } 158 159 for (Student stus : Stus) {//对每一个学生进行处理//此时学生不会重复 160 //对该学生进行处理 161 stu = stus; 162 163 //把该学生的每一个课程成绩加入课程链表之中 164 for (int j = 0; j < stu.getGrad().size(); j++) { 165 CSGrad = stu.getGrad().get(j); 166 k = seaC(CSGrad.getName(), CourL); 167 cour = CourL.get(k); 168 cour.getGrad().add(CSGrad.getGrad()); 169 } 170 171 //创建班级 172 k = seaCl(stu.getNum(), ClassL); 173 if (k == -1) {//班级不存在 174 int[] Cum = Arrays.copyOfRange(stu.getNum(), 0, 6); 175 ClassL.add(new Classes(Cum)); 176 k = seaCl(stu.getNum(), ClassL); 177 } 178 ClassL.get(k).getStus().add(stu);//学生加入班级 179 } 180 181 //对学号排序 182 Collections.sort(Stus); 183 184 //对课程排序 185 Comparator<Course> comparator = new Comparator<>() { 186 Collator CourLlator = Collator.getInstance(Locale.CHINA); 187 @Override 188 public int compare(Course o1, Course o2) { 189 return CourLlator.compare(o1.getName(), o2.getName()); 190 } 191 }; 192 Collections.sort(CourL, comparator); 193 194 //对班级排序 195 Collections.sort(ClassL); 196 197 //输出学生所有课程总成绩的平均分 198 for (Student v : Stus) { 199 int sum = 0; 200 int len = v.getGrad().size(); 201 for (int j = 0; j < len; j++) { 202 sum += v.getGrad().get(j).getGrad().getGrad(); 203 } 204 prNum(v.getNum()); 205 if(len != 0){ 206 sum /= len; 207 pr(" " + v.getName() + " " + sum); 208 } 209 else{ 210 pr(" " + v.getName() + " did not take any exams"); 211 } 212 } 213 214 //输出课程单门课程成绩平均分 215 for (Course co : CourL) { 216 int a = 0, b = 0, c = 0, len = co.getGrad().size(); 217 for (int j = 0; j < len; j++) { 218 grad = co.getGrad().get(j); 219 a += grad.getUs(); 220 b += grad.getFin(); 221 c += grad.getGrad(); 222 } 223 if(len != 0){ 224 a /= len; 225 b /= len; 226 c /= len; 227 228 if (a != 0) { 229 pr(co.getName() + " " + a + " " + b + " " + c); 230 } else { 231 pr(co.getName() + " " + b + " " + c); 232 } 233 } 234 else{ 235 pr(co.getName() + " " + "has no grades yet"); 236 } 237 238 } 239 240 //输出班级所有课程总成绩平均分 241 for (Classes v : ClassL) { 242 int sum = 0,count = 0; 243 int len = v.getStus().size(); 244 for (int j = 0; j < len; j++) { 245 stu = v.getStus().get(j); 246 for(int l = 0;l < stu.getGrad().size();l ++){ 247 sum += stu.getGrad().get(l).getGrad().getGrad(); 248 count ++; 249 } 250 } 251 prNum(v.getNum()); 252 253 if(count != 0){ 254 sum /= count; 255 pr(" " + sum); 256 } 257 else{ 258 pr(" has no grades yet"); 259 } 260 } 261 } 262 263 //查看班级是否存在 264 public static int seaCl(int[] n,ArrayList<Classes> cl){ 265 for(int i = 0;i < cl.size();i ++){ 266 n = Arrays.copyOfRange(n,0,6); 267 int[] s = Arrays.copyOfRange(cl.get(i).getNum(), 0, 6); 268 if(Arrays.equals(n,s)) { 269 return i; 270 } 271 } 272 return -1; 273 } 274 275 //查看学生是否存在 276 public static int seaS(int[] n,ArrayList<Student> s){ 277 for(int i = 0;i < s.size();i ++){ 278 int[] stu = s.get(i).getNum(); 279 if(Arrays.equals(n,stu)) { 280 return i; 281 } 282 } 283 return -1; 284 } 285 286 public static int seaTT(int[] num,String n,String coN,ArrayList<CoSe> list){ 287 for(int i = 0;i < list.size();i ++){ 288 CoSe co = list.get(i); 289 Student s = co.getStu(); 290 if(Arrays.equals(num,s.getNum()) && n.equals(s.getName()) && coN.equals(co.getCo().getName())){ 291 return i; 292 } 293 } 294 return -1; 295 } 296 297 public static int seaC(String n,ArrayList<Course> list){//查找课程是否存在 298 for(int i = 0;i < list.size();i ++) { 299 if(list.get(i).getName().equals(n)) 300 return i; 301 } 302 return -1; 303 } 304 305 //输出数组数组 306 public static void prNum(int[] num){ 307 for (int i : num) System.out.print(i); 308 } 309 310 public static void prW(){ 311 pr("wrong format"); 312 } 313 314 public static void pr(String s){ 315 System.out.println(s); 316 } 317 318 } 319 320 //课程类 321 class Course { 322 private String name;//课程名字 323 private String nature;//课程性质 324 private String ass;//考核方式 325 private ArrayList<AbGrad> grad = new ArrayList<>();//每一个学生课程成绩 326 327 public Course() { 328 } 329 330 public Course(String name, String nature, String ass) { 331 this.name = name; 332 this.nature = nature; 333 this.ass = ass; 334 } 335 336 public String getName() { 337 return name; 338 } 339 340 public String getNa() { 341 return nature; 342 } 343 344 public String getAss() { 345 return ass; 346 } 347 348 public ArrayList<AbGrad> getGrad() { 349 return grad; 350 } 351 352 public boolean MathAss(String ass){//课程是否与考核方式以及成绩数量匹配 353 return getAss().equals(ass); 354 } 355 356 public boolean MathNa(String ass){//课程是否与考核方式以及成绩数量匹配 357 return getNa().equals(ass); 358 } 359 360 public boolean isNa(String a,String b){ 361 return ((a.equals("必修") && b.equals("考试")) || a.equals("选修")); 362 } 363 } 364 365 //成绩类 366 abstract class AbGrad{ 367 private int usGrad; 368 private int finGrad; 369 private int grad; 370 371 public AbGrad() { 372 } 373 374 public void setUs(int usGrad) { 375 this.usGrad = usGrad; 376 } 377 378 public void setFin(int finGrad) { 379 this.finGrad = finGrad; 380 } 381 382 public int getUs() { 383 return usGrad; 384 } 385 386 public int getFin() { 387 return finGrad; 388 } 389 390 public int getGrad() { 391 return grad; 392 } 393 394 public void setGrad(int grad) { 395 this.grad = grad; 396 } 397 } 398 399 //考试成绩类 400 class ExGrad extends AbGrad{ 401 public ExGrad() { 402 } 403 404 public ExGrad(int usGrad, int finGrad) { 405 this.setUs(usGrad); 406 this.setFin(finGrad); 407 } 408 409 public void CalGrad() { 410 setGrad((int) Math.floor(0.3 * getUs() + 0.7 * getFin())); 411 } 412 } 413 414 //考察成绩类 415 class ExineGrad extends AbGrad{ 416 public ExineGrad() { 417 } 418 419 public ExineGrad(int finGrad) { 420 this.setFin(finGrad); 421 } 422 423 public void CalGrad() { 424 setGrad(getFin()); 425 } 426 } 427 428 //班级类 429 class Classes implements Comparable<Classes>{ 430 private ArrayList<Student> Stus = new ArrayList<>(); 431 private int[] num; 432 433 public Classes(int[] num) { 434 this.num = num; 435 } 436 437 public ArrayList<Student> getStus() { 438 return Stus; 439 } 440 441 public int[] getNum() { 442 return num; 443 } 444 445 public int compareTo(Classes o) { 446 int[] n = getNum(); 447 int[] c = o.getNum(); 448 int i = 0; 449 while (i < 8) { 450 if(n[i] > c[i]) return 1; 451 if(n[i] < c[i]) return -1; 452 i++; 453 } 454 return -1; 455 456 } 457 } 458 459 //学生类 460 class Student implements Comparable<Student>{ 461 private int[] num = new int[8]; 462 private String name; 463 464 //每一个是学生一门课程的成绩 465 ArrayList<CourStuGrad> grad = new ArrayList<>(); 466 467 public Student() { 468 } 469 470 public int[] getNum() { 471 return num; 472 } 473 474 public void setNum(int[] n) { 475 this.num = n; 476 } 477 478 public String getName() { 479 return name; 480 } 481 482 public void setName(String name) { 483 this.name = name; 484 } 485 486 public ArrayList<CourStuGrad> getGrad() { 487 return grad; 488 } 489 490 public void StrToInt(String s){//学号的字符串转数字数组 491 int[] arr = new int[s.length()]; 492 int i = 0; 493 while (i < arr.length) { 494 Character ch = s.charAt(i); 495 arr[i] = Integer.parseInt(ch.toString()); 496 i++; 497 } 498 setNum(arr); 499 } 500 501 public void AGrad(String name,AbGrad abstractGrades){ 502 getGrad().add(new CourStuGrad(name,abstractGrades)); 503 } 504 505 @Override 506 public int compareTo(Student o) { 507 int[] num = getNum(); 508 int[] cum = o.getNum(); 509 int i = 0; 510 while (i < 8) { 511 if(num[i] > cum[i]) return 1; 512 if(num[i] < cum[i]) return -1; 513 i++; 514 } 515 return -1; 516 } 517 } 518 519 //课程-学生成绩 520 //对于一名学生,一门课程的成绩 521 class CourStuGrad{ 522 private String name;//课程名称 523 private AbGrad grad; 524 525 public CourStuGrad(String name, AbGrad grad) { 526 this.name = name; 527 this.grad = grad; 528 } 529 530 public String getName() { 531 return name; 532 } 533 534 public AbGrad getGrad() { 535 return grad; 536 } 537 } 538 539 540 //选课 541 class CoSe{ 542 Course cour = new Course(); 543 Student stu = new Student(); 544 AbGrad grad;//学生stu在该门课cour下的成绩grad 545 546 public CoSe() { 547 } 548 549 public Course getCo() { 550 return cour; 551 } 552 553 public void setCour(Course cour) { 554 this.cour = cour; 555 } 556 557 public void setStu(Student stu) { 558 this.stu = stu; 559 } 560 561 public Student getStu() { 562 return stu; 563 } 564 565 public AbGrad getGrad() { 566 return grad; 567 } 568 569 public void setGrad(AbGrad grad) { 570 this.grad = grad; 571 } 572 }
(2)10-3
本题是课程成绩统计的第一次迭代,相较于课程1,增加了“实验课”的相关内容及限制,大的框架并没有发生改变,限制约束条件基本也是原来的,只是添加了新的内容。在设计中只需仿照原本的考察类、考试类设计编写实验类相关内容就可以,整体设计难度不大。
<1> 本次设计中我被困的最久的是实验类的正则表达式一直匹配不上,这是第一版
Pattern pExper = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([4-9])(( [0-9]|[1-9][0-9]|100)+)");
这是最后一版
Pattern pExper = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([4-9])(( \\d{1,2}| 100)+)");
看上去差别不大,但不断地测试修改、查找资料,找各种同学讨论真的挺折磨的,但也因此记住了匹配0-100的正则()
<2> 其次就是一些细节上的问题,因为新加了实验课,主方法肯定是需要修改的,各种细节的部分就要把实验的相关信息给加上,还有各个方法中的实验课相关信息也是要进行一些调整。
如图,其实把本次代码的框架搭好后并没有遇到什么大问题,在第四次提交时就到了56/60分,然后后面就一直卡在56分就是因为小细节上忘记将实验类的信息加上,但在不断的各种问同学和同学讨论都没发现什么大问题下,最后实在没有办法了,就自己一行行代码看了一遍,把问题给揪了出来。举个例子
1 public boolean isNa(String a,String b){ 2 return ((a.equals("必修") && b.equals("考试")) || a.equals("选修") && !b.equals("实验") || (a.equals("实验") && b.equals("实验"))); 3 }
像这种地方,在某个类中的某个方法,因为是在课程1的基础上改的,所以原来的判定中是没有实验相关的,就是不会容易想起来这里要加上。还有像
1 if (co.getAss().equals("考试")) { 2 pr(co.getName() + " " + a + " " + b + " " + c); 3 } else if(co.getAss().equals("考察")) { 4 pr(co.getName() + " " + b + " " + c); 5 } else{ 6 pr(co.getName() + " " + c); 7 }
这种地方,就一不留神就忘记要把实验的输出给加上等等地方。
最后代码如下:
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 10 int k; 11 CoSe coSe; 12 Course cour; 13 Student stu; 14 AbGrad grad; 15 ExGrad ex; 16 ExineGrad exine; 17 ExperGrad exper; 18 CourStuGrad CSGrad; 19 20 ArrayList<Course> CourL = new ArrayList<>(); 21 ArrayList<Student> Stus = new ArrayList<>(); 22 ArrayList<Classes> ClassL = new ArrayList<>(); 23 ArrayList<CoSe> coSeL = new ArrayList<>(); 24 25 String s,z = null,z4,z5,ep = null; 26 Pattern pCour = Pattern.compile("(\\S{1,10}) (必修|选修|实验) (考试|考察|实验)"); 27 Pattern pEx = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)"); 28 Pattern pExine = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100)"); 29 Pattern pExper = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([4-9])(( \\d{1,2}| 100)+)"); 30 Pattern pend = Pattern.compile("end"); 31 Matcher mCour,mEx,mExine,mExper,mend; 32 33 //输入 34 while(true){ 35 s = in.nextLine(); 36 mCour = pCour.matcher(s); 37 mEx = pEx.matcher(s); 38 mExine = pExine.matcher(s); 39 mExper = pExper.matcher(s); 40 41 boolean fa = mEx.matches(); 42 boolean fb = mExine.matches(); 43 boolean fc = mExper.matches(); 44 45 mend = pend.matcher(s); 46 47 coSe = new CoSe(); 48 stu = coSe.getStu(); 49 50 if(mend.matches()){ 51 break; 52 } 53 54 else if(mCour.matches()){//课程信息 55 //加入所有课程的列表 56 z = mCour.group(1); 57 z4 = mCour.group(2); 58 z5 = mCour.group(3); 59 cour = new Course(z,z4,z5); 60 61 //异常情况:输入的课程性质是否和课程的考核方式匹配 62 if(cour.isNa(z4,z5)){ 63 if(seaC(z,CourL) == -1) 64 CourL.add(cour); 65 } 66 else{ 67 pr(cour.getName() + " : course type & access mode mismatch"); 68 } 69 } 70 else if(fa || fb || fc){//考试的课程成绩 //考察的课程成绩 //实验的课程 71 ArrayList<Integer> Exp = new ArrayList<>(); 72 int a = 0,b = 0,flag = 0; 73 if(fa){ 74 //学号的字符串转数字数组 75 stu.StrToInt(mEx.group(1));//学号 76 stu.setName(mEx.group(2));//姓名 77 78 z = mEx.group(3); 79 a = Integer.parseInt(mEx.group(4)); 80 b = Integer.parseInt(mEx.group(5)); 81 } 82 if(fb){ 83 stu.StrToInt(mExine.group(1));//学号 84 stu.setName(mExine.group(2));//姓名 85 86 z = mExine.group(3); 87 a = Integer.parseInt(mExine.group(4)); 88 } 89 if(fc){ 90 stu.StrToInt(mExper.group(1));//学号 91 stu.setName(mExper.group(2));//姓名 92 93 z = mExper.group(3); 94 a = Integer.parseInt(mExper.group(4));//有几次实验 95 String[] epp = s.trim().split(" "); 96 for(int i = 4;i < epp.length;i ++){ 97 Exp.add(Integer.parseInt(epp[i])); 98 } 99 } 100 101 k = seaC(z,CourL); 102 //异常情况:课程名称不在已输入的课程列表中 103 if(k == -1){ 104 pr(z +" does not exist"); 105 } 106 else { 107 //如果没有重复的课程成绩信息 108 if(seaTT(stu.getNum(), stu.getName(),z,coSeL) == -1){ 109 cour = CourL.get(k); 110 coSe.setCour(cour);//根据课程名字加入 111 112 //异常情况:输入的成绩数量和课程的考核方式不匹配 113 if(fa){ 114 if(!cour.MathAss("考试")) {//找到课程名字,看是否为考试 115 flag = 1; 116 } 117 else{ 118 coSe.setGrad(new ExGrad(a,b));//把课程成绩输入找到对应课程 119 } 120 } 121 if(fb){ 122 if(!cour.MathAss("考察") || !cour.MathNa("选修")) {//找到课程名字,看是否为考察 123 flag = 1; 124 } 125 else{ 126 coSe.setGrad(new ExineGrad(a));//把课程成绩输入找到对应课程 127 } 128 } 129 if(fc){ 130 if(!cour.MathAss("实验") || !cour.MathNa("实验") || a != s.trim().split(" ").length - 4) {//找到课程名字,看是否为实验//实验次数是否对的上 131 flag = 1; 132 } 133 else{ 134 coSe.setGrad(new ExperGrad(Exp));//把课程成绩输入找到对应课程 135 } 136 } 137 if(flag == 1){ 138 prNum(stu.getNum()); 139 pr(" " + stu.getName() +" : access mode mismatch"); 140 } 141 } 142 } 143 coSe.setStu(stu); 144 coSeL.add(coSe); 145 } 146 //格式错误以及其他信息异常如成绩超出范围 147 else { 148 prW(); 149 } 150 } 151 152 for (CoSe sl : coSeL) {//对于每一组数据分别储存 153 //对于这个学生开始操作 154 int[] num = sl.getStu().getNum(); 155 cour = sl.getCo(); 156 stu = sl.getStu(); 157 grad = sl.getGrad(); 158 k = seaS(num,Stus); 159 String str = cour.getAss(); 160 161 //存入Student,Stus 162 if (k == -1) {//学生不存在 163 Stus.add(stu); 164 k = seaS(num,Stus); 165 } 166 167 if(str != null && grad != null){ 168 //计算学生成绩,存入学生数据 169 if (str.equals("考试")) { 170 //计算总成绩 171 ex = (ExGrad) grad; 172 ex.CalGrad(); 173 //找到这个学生,赋给成绩 174 Stus.get(k).AGrad(cour.getName(), ex); 175 } 176 if (str.equals("考察")) { 177 exine = (ExineGrad) grad; 178 exine.CalGrad(); 179 //找到这个学生,赋给成绩 180 Stus.get(k).AGrad(cour.getName(), exine); 181 } 182 if (str.equals("实验")) { 183 exper = (ExperGrad) grad; 184 exper.CalGrad(); 185 //找到这个学生,赋给成绩 186 Stus.get(k).AGrad(cour.getName(), exper); 187 } 188 } 189 190 } 191 192 for (Student stus : Stus) {//对每一个学生进行处理//此时学生不会重复 193 //对该学生进行处理 194 stu = stus; 195 196 //把该学生的每一个课程成绩加入课程链表之中 197 for (int j = 0; j < stu.getGrad().size(); j++) { 198 CSGrad = stu.getGrad().get(j); 199 cour = CourL.get(seaC(CSGrad.getName(), CourL)); 200 cour.getGrad().add(CSGrad.getGrad()); 201 } 202 203 //创建班级 204 k = seaCl(stu.getNum(), ClassL); 205 if (k == -1) {//班级不存在 206 int[] Cum = Arrays.copyOfRange(stu.getNum(), 0, 6); 207 ClassL.add(new Classes(Cum)); 208 k = seaCl(stu.getNum(), ClassL); 209 } 210 ClassL.get(k).getStus().add(stu);//学生加入班级 211 } 212 213 //对学号排序 214 Collections.sort(Stus); 215 216 //对课程排序 217 Comparator<Course> comparator = new Comparator<>() { 218 Collator CourLlator = Collator.getInstance(Locale.CHINA); 219 @Override 220 public int compare(Course o1, Course o2) { 221 return CourLlator.compare(o1.getName(), o2.getName()); 222 } 223 }; 224 Collections.sort(CourL, comparator); 225 226 //对班级排序 227 Collections.sort(ClassL); 228 229 //输出学生所有课程总成绩的平均分 230 for (Student v : Stus) { 231 int sum = 0; 232 int len = v.getGrad().size(); 233 for (int j = 0; j < len; j++) { 234 sum += v.getGrad().get(j).getGrad().getGrad(); 235 } 236 prNum(v.getNum()); 237 if(len != 0){ 238 sum /= len; 239 pr(" " + v.getName() + " " + sum); 240 } 241 else{ 242 pr(" " + v.getName() + " did not take any exams"); 243 } 244 } 245 246 //输出课程单门课程成绩平均分 247 for (Course co : CourL) { 248 int a = 0, b = 0, c = 0, len = co.getGrad().size(); 249 for (int j = 0; j < len; j++) { 250 grad = co.getGrad().get(j); 251 a += grad.getUs(); 252 b += grad.getFin(); 253 c += grad.getGrad(); 254 } 255 if(len != 0){ 256 a /= len; 257 b /= len; 258 c /= len; 259 260 if (co.getAss().equals("考试")) { 261 pr(co.getName() + " " + a + " " + b + " " + c); 262 } else if(co.getAss().equals("考察")) { 263 pr(co.getName() + " " + b + " " + c); 264 } else{ 265 pr(co.getName() + " " + c); 266 } 267 } 268 else{ 269 pr(co.getName() + " " + "has no grades yet"); 270 } 271 272 } 273 274 //输出班级所有课程总成绩平均分 275 for (Classes v : ClassL) { 276 int sum = 0,count = 0; 277 int len = v.getStus().size(); 278 for (int j = 0; j < len; j++) { 279 stu = v.getStus().get(j); 280 for(int l = 0;l < stu.getGrad().size();l ++){ 281 sum += stu.getGrad().get(l).getGrad().getGrad(); 282 count ++; 283 } 284 } 285 prNum(v.getNum()); 286 287 if(count != 0){ 288 sum /= count; 289 pr(" " + sum); 290 } 291 else{ 292 pr(" has no grades yet"); 293 } 294 } 295 } 296 297 //查看班级是否存在 298 public static int seaCl(int[] n,ArrayList<Classes> cl){ 299 for(int i = 0;i < cl.size();i ++){ 300 n = Arrays.copyOfRange(n,0,6); 301 int[] s = Arrays.copyOfRange(cl.get(i).getNum(), 0, 6); 302 if(Arrays.equals(n,s)) { 303 return i; 304 } 305 } 306 return -1; 307 } 308 309 //查看学生是否存在 310 public static int seaS(int[] n,ArrayList<Student> s){ 311 for(int i = 0;i < s.size();i ++){ 312 int[] stu = s.get(i).getNum(); 313 if(Arrays.equals(n,stu)) { 314 return i; 315 } 316 } 317 return -1; 318 } 319 320 public static int seaTT(int[] num,String n,String coN,ArrayList<CoSe> list){ 321 //该门课程下学生的成绩不为空 322 for(int i = 0;i < list.size();i ++){ 323 CoSe co = list.get(i); 324 Student s = co.getStu(); 325 if(Arrays.equals(num,s.getNum()) && n.equals(s.getName()) && coN.equals(co.getCo().getName()) && co.getGrad() != null){ 326 return i; 327 } 328 } 329 return -1; 330 } 331 332 public static int seaC(String n,ArrayList<Course> list){//查找课程是否存在 333 for(int i = 0;i < list.size();i ++) { 334 if(list.get(i).getName().equals(n)) 335 return i; 336 } 337 return -1; 338 } 339 340 //输出数组数组 341 public static void prNum(int[] num){ 342 for (int i : num) System.out.print(i); 343 } 344 345 public static void prW(){ 346 pr("wrong format"); 347 } 348 349 public static void pr(String s){ 350 System.out.println(s); 351 } 352 353 } 354 355 //课程类 356 class Course { 357 private String name;//课程名字 358 private String nature;//课程性质 359 private String ass;//考核方式 360 private ArrayList<AbGrad> grad = new ArrayList<>();//每一个学生课程成绩 361 362 public Course() { 363 } 364 365 public Course(String name, String nature, String ass) { 366 this.name = name; 367 this.nature = nature; 368 this.ass = ass; 369 } 370 371 public String getName() { 372 return name; 373 } 374 375 public String getNa() { 376 return nature; 377 } 378 379 public String getAss() { 380 return ass; 381 } 382 383 public ArrayList<AbGrad> getGrad() { 384 return grad; 385 } 386 387 public boolean MathAss(String ass){//课程是否是所要求的考核方式的课程 388 return getAss().equals(ass); 389 } 390 391 public boolean MathNa(String ass){//课程是否是所要求的性质 392 return getNa().equals(ass); 393 } 394 395 public boolean isNa(String a,String b){ 396 return ((a.equals("必修") && b.equals("考试")) || a.equals("选修") && !b.equals("实验") || (a.equals("实验") && b.equals("实验"))); 397 } 398 } 399 400 //成绩类 401 abstract class AbGrad{ 402 private int usGrad; 403 private int finGrad; 404 private int grad; 405 406 public AbGrad() { 407 } 408 409 public void setUs(int usGrad) { 410 this.usGrad = usGrad; 411 } 412 413 public void setFin(int finGrad) { 414 this.finGrad = finGrad; 415 } 416 417 public int getUs() { 418 return usGrad; 419 } 420 421 public int getFin() { 422 return finGrad; 423 } 424 425 public int getGrad() { 426 return grad; 427 } 428 429 public void setGrad(int grad) { 430 this.grad = grad; 431 } 432 433 public abstract void CalGrad(); 434 } 435 436 //考试成绩类 437 class ExGrad extends AbGrad{ 438 public ExGrad() { 439 } 440 441 public ExGrad(int usGrad, int finGrad) { 442 this.setUs(usGrad); 443 this.setFin(finGrad); 444 } 445 446 public void CalGrad() { 447 setGrad((int) Math.floor(0.3 * getUs() + 0.7 * getFin())); 448 } 449 } 450 451 //考察成绩类 452 class ExineGrad extends AbGrad{ 453 public ExineGrad() { 454 } 455 456 public ExineGrad(int finGrad) { 457 this.setFin(finGrad); 458 } 459 460 public void CalGrad() { 461 setGrad(getFin()); 462 } 463 } 464 465 //实验成绩类 466 class ExperGrad extends AbGrad{ 467 ArrayList<Integer> gr = new ArrayList<>(); 468 public ExperGrad(ArrayList<Integer> exp){ 469 setGr(exp); 470 } 471 472 public void setGr(ArrayList<Integer> gr) { 473 this.gr = gr; 474 } 475 476 @Override 477 public void CalGrad() { 478 int sum = 0; 479 for(int v : gr){ 480 sum += v; 481 } 482 sum /= gr.size(); 483 setGrad(sum); 484 } 485 } 486 487 //班级类 488 class Classes implements Comparable<Classes>{ 489 private ArrayList<Student> Stus = new ArrayList<>(); 490 private int[] num; 491 492 public Classes(int[] num) { 493 this.num = num; 494 } 495 496 public ArrayList<Student> getStus() { 497 return Stus; 498 } 499 500 public int[] getNum() { 501 return num; 502 } 503 504 public int compareTo(Classes o) { 505 int[] n = getNum(); 506 int[] c = o.getNum(); 507 int i = 0; 508 while (i < 8) { 509 if(n[i] > c[i]) return 1; 510 if(n[i] < c[i]) return -1; 511 i++; 512 } 513 return -1; 514 515 } 516 } 517 518 //学生类 519 class Student implements Comparable<Student>{ 520 private int[] num = new int[8]; 521 private String name; 522 523 //每一个是学生一门课程的成绩 524 ArrayList<CourStuGrad> grad = new ArrayList<>(); 525 526 public Student() { 527 } 528 529 public int[] getNum() { 530 return num; 531 } 532 533 public void setNum(int[] n) { 534 this.num = n; 535 } 536 537 public String getName() { 538 return name; 539 } 540 541 public void setName(String name) { 542 this.name = name; 543 } 544 545 public ArrayList<CourStuGrad> getGrad() { 546 return grad; 547 } 548 549 public void StrToInt(String s){//学号的字符串转数字数组 550 int[] arr = new int[s.length()]; 551 int i = 0; 552 while (i < arr.length) { 553 Character ch = s.charAt(i); 554 arr[i] = Integer.parseInt(ch.toString()); 555 i++; 556 } 557 setNum(arr); 558 } 559 560 public void AGrad(String name,AbGrad abstractGrades){ 561 getGrad().add(new CourStuGrad(name,abstractGrades)); 562 } 563 564 @Override 565 public int compareTo(Student o) { 566 int[] num = getNum(); 567 int[] cum = o.getNum(); 568 int i = 0; 569 while (i < 8) { 570 if(num[i] > cum[i]) return 1; 571 if(num[i] < cum[i]) return -1; 572 i++; 573 } 574 return -1; 575 } 576 } 577 578 //课程-学生成绩 579 //对于一名学生,一门课程的成绩 580 class CourStuGrad{ 581 private String name;//课程名称 582 private AbGrad grad; 583 584 public CourStuGrad(String name, AbGrad grad) { 585 this.name = name; 586 this.grad = grad; 587 } 588 589 public String getName() { 590 return name; 591 } 592 593 public AbGrad getGrad() { 594 return grad; 595 } 596 } 597 598 599 //选课 600 class CoSe{ 601 Course cour = new Course(); 602 Student stu = new Student(); 603 AbGrad grad;//学生stu在该门课cour下的成绩grad 604 605 public CoSe() { 606 } 607 608 public Course getCo() { 609 return cour; 610 } 611 612 public void setCour(Course cour) { 613 this.cour = cour; 614 } 615 616 public void setStu(Student stu) { 617 this.stu = stu; 618 } 619 620 public Student getStu() { 621 return stu; 622 } 623 624 public AbGrad getGrad() { 625 return grad; 626 } 627 628 public void setGrad(AbGrad grad) { 629 this.grad = grad; 630 } 631 }
(3)11-2
本次题目就改动较大了,基本是要重新设计
类间关系由继承变为了组合,其实一开始我是有点没有看懂他是想表达什么意思的,是怎么个组合方式有点迷迷糊糊,后来再看几遍大致懂了之后为了确保没弄错还和同学对了一下(就我也觉得自己有点离谱),其他方面的改动比如增加了权重值,从固定的权重变成了输入权重,以及最重要的计算成绩发生了变化,比之前的计算简单了许多,如下
还有的就是随着权重值的输入增加了两种异常情况
对于本道第三次迭代,其实虽然在理解题目时有点差错,但在编写时其实感觉并不会难以下手,因为有了前两次的基础,对题目的各个类和各个属性的并不陌生,一路写下来其实是比较顺畅。
类图设计如下
最后代码如下:
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 10 int k; 11 CoSe coSe; 12 Course cour; 13 Student stu; 14 ExGrad ex = new ExGrad(); 15 ExineGrad exine = new ExineGrad(); 16 ExperGrad exper = new ExperGrad(); 17 CourStuGrad CSGrad; 18 19 ArrayList<Course> CourL = new ArrayList<>(); 20 ArrayList<Student> Stus = new ArrayList<>(); 21 ArrayList<Classes> ClassL = new ArrayList<>(); 22 ArrayList<CoSe> coSeL = new ArrayList<>(); 23 24 String s,z = null,z4 = null,z5 = null,ep = null; 25 Pattern pCour = Pattern.compile("(\\S{1,10}) (必修|选修|实验) (考试|考察|实验)"); 26 Pattern pCoEx = Pattern.compile("(\\S{1,10}) (必修|选修|实验) (考试) [0-9]+(.[0-9]{1,2})? [0-9]+(.[0-9]{1,2})?"); 27 Pattern pCoExine = Pattern.compile("(\\S{1,10}) (必修|选修|实验) (考察)"); 28 Pattern pCoExper = Pattern.compile("(\\S{1,10}) 实验 实验 ([4-9])(( [0-9]+(.[0-9]{1,2})?)+)"); 29 Pattern pEx = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100) ([0-9]|[1-9][0-9]|100)"); 30 Pattern pExine = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10}) ([0-9]|[1-9][0-9]|100)"); 31 Pattern pExper = Pattern.compile("(\\d{8}) (\\S{1,10}) (\\S{1,10})(( \\d{1,2}| 100)+)"); 32 Pattern pend = Pattern.compile("end"); 33 Matcher mCoEx,mCoExine,mCoExper,mEx,mExine,mExper,mend; 34 35 //输入 36 while(true){ 37 s = in.nextLine(); 38 mCoEx = pCoEx.matcher(s); 39 mCoExine = pCoExine.matcher(s); 40 mCoExper = pCoExper.matcher(s); 41 mEx = pEx.matcher(s); 42 mExine = pExine.matcher(s); 43 mExper = pExper.matcher(s); 44 45 boolean ma = mCoEx.matches(); 46 boolean mb = mCoExine.matches(); 47 boolean mc = mCoExper.matches(); 48 boolean fa = mEx.matches(); 49 boolean fb = mExine.matches(); 50 boolean fc = mExper.matches(); 51 52 mend = pend.matcher(s); 53 54 coSe = new CoSe(); 55 stu = coSe.getStu(); 56 57 if(mend.matches()){ 58 break; 59 } 60 61 else if(ma || mb || mc){//课程信息 62 ArrayList<Float> ite = new ArrayList<>(); 63 if(ma){ 64 //加入所有课程的列表 65 z = mCoEx.group(1); 66 z4 = mCoEx.group(2); 67 z5 = mCoEx.group(3); 68 ite.add(Float.parseFloat(mCoEx.group(4))); 69 ite.add(Float.parseFloat(mCoEx.group(5))); 70 } 71 else if(mb){ 72 z = mCoExine.group(1); 73 z4 = mCoExine.group(2); 74 z5 = mCoExine.group(3); 75 ite.add(1.0F); 76 } 77 // if(mc){ 78 else{ 79 z = mCoExper.group(1); 80 z4 = "实验"; 81 z5 = "实验"; 82 int l = Integer.parseInt(mCoExper.group(2));//有几次实验 83 String[] epp = s.trim().split(" "); 84 for(int i = 4;i < epp.length;i ++){ 85 ite.add(Float.parseFloat(epp[i])); 86 } 87 88 //异常情况:输入的分项成绩数量值和分项成绩权重的个数不匹配 89 if(l != ite.size()){ 90 System.out.println(z + " : number of scores does not match"); 91 mc = false; 92 } 93 } 94 95 //异常情况:如果解析考试课、实验课时,分项成绩权重值的总和不等于1 96 if(ma || mc){ 97 float sum = 0; 98 for(float v : ite){ 99 sum += v; 100 } 101 if((Math.abs(sum - 1.0) / Math.max(sum,1.0)) > 0.000001){//不相等 102 System.out.println(z + " : weight value error"); 103 ma = false; 104 mc = false; 105 } 106 } 107 108 cour = new Course(z,z4,z5,ite); 109 110 //异常情况:输入的课程性质是否和课程的考核方式匹配 111 if(cour.isNa(z4,z5)){ 112 if(seaC(z,CourL) == -1){ 113 if(ma || mb || mc) 114 CourL.add(cour); 115 } 116 } 117 else{ 118 pr(cour.getName() + " : course type & access mode mismatch"); 119 } 120 } 121 else if(fa || fb || fc){//考试的课程成绩 //考察的课程成绩 //实验的课程 122 ArrayList<Integer> Exp = new ArrayList<>(); 123 int a = 0,b = 0,flag = 0; 124 if(fa){ 125 //学号的字符串转数字数组 126 stu.StrToInt(mEx.group(1));//学号 127 stu.setName(mEx.group(2));//姓名 128 129 z = mEx.group(3); 130 a = Integer.parseInt(mEx.group(4)); 131 b = Integer.parseInt(mEx.group(5)); 132 } 133 else if(fb){ 134 stu.StrToInt(mExine.group(1));//学号 135 stu.setName(mExine.group(2));//姓名 136 137 z = mExine.group(3); 138 a = Integer.parseInt(mExine.group(4)); 139 } 140 // if(fc){ 141 else{ 142 stu.StrToInt(mExper.group(1));//学号 143 stu.setName(mExper.group(2));//姓名 144 145 z = mExper.group(3); 146 // a = Integer.parseInt(mExper.group(4));//有几次实验 147 String[] epp = s.trim().split(" "); 148 for(int i = 3;i < epp.length;i ++){ 149 Exp.add(Integer.parseInt(epp[i])); 150 } 151 } 152 153 k = seaC(z,CourL); 154 //异常情况:课程名称不在已输入的课程列表中 155 if(k == -1){ 156 pr(z +" does not exist"); 157 } 158 else { 159 //如果没有重复的课程成绩信息 160 if(seaTT(stu.getNum(), stu.getName(),z,coSeL) == -1){ 161 cour = CourL.get(k); 162 coSe.setCour(cour);//根据课程名字加入 163 164 //异常情况:输入的成绩数量和课程的考核方式不匹配 165 if(fa){ 166 if(!cour.MathAss("考试")) {//找到课程名字,看是否为考试 167 flag = 1; 168 } 169 else{ 170 //在课程列表中找到对应课程,把成绩和权重赋给成绩 171 coSe.setExGrad(new ExGrad(a,CourL.get(k).getIte().get(0),b,CourL.get(k).getIte().get(1))); 172 // coSe.setGrad(new ExGrad(a,b));//把课程成绩输入找到对应课程 173 } 174 } 175 else if(fb){ 176 if(!cour.MathAss("考察") || !cour.MathNa("选修")) {//找到课程名字,看是否为考察 177 flag = 1; 178 } 179 else{ 180 coSe.setExineGrad(new ExineGrad(a,CourL.get(k).getIte().get(0))); 181 // coSe.setGrad(new ExineGrad(a));//把课程成绩输入找到对应课程 182 } 183 } 184 // if(fc){ 185 else{ 186 if(!cour.MathAss("实验") || !cour.MathNa("实验") || CourL.get(k).getIte().size() != s.trim().split(" ").length - 3) {//找到课程名字,看是否为实验//实验次数是否对的上 187 flag = 1; 188 } 189 else{ 190 coSe.setExperGrad(new ExperGrad(Exp,CourL.get(k).getIte()));//把课程成绩输入找到对应课程 191 } 192 } 193 if(flag == 1){ 194 prNum(stu.getNum()); 195 pr(" " + stu.getName() +" : access mode mismatch"); 196 } 197 } 198 } 199 coSe.setStu(stu); 200 coSeL.add(coSe); 201 } 202 //格式错误以及其他信息异常如成绩超出范围 203 else { 204 prW(); 205 } 206 } 207 208 for (CoSe sl : coSeL) {//对于每一组数据分别储存 209 //对于这个学生开始操作 210 int[] num = sl.getStu().getNum(); 211 cour = sl.getCo(); 212 stu = sl.getStu(); 213 ex = sl.getExGrad(); 214 exine = sl.getExineGrad(); 215 exper = sl.getExperGrad(); 216 k = seaS(num,Stus); 217 String str = cour.getAss(); 218 219 //存入Student,Stus 220 if (k == -1) {//学生不存在 221 Stus.add(stu); 222 k = seaS(num,Stus); 223 } 224 225 if(str != null && (ex != null || exine != null || exper != null )){ 226 //计算学生成绩,存入学生数据 227 if (str.equals("考试")) { 228 //计算总成绩 229 // ex = (ExGrad) grad; 230 // ex.CalGrad(); 231 //找到这个学生,赋给成绩 232 Stus.get(k).AGrad(cour.getName(), ex.CalGrad()); 233 } 234 if (str.equals("考察")) { 235 //找到这个学生,赋给成绩 236 Stus.get(k).AGrad(cour.getName(), exine.CalGrad()); 237 } 238 if (str.equals("实验")) { 239 //找到这个学生,赋给成绩 240 Stus.get(k).AGrad(cour.getName(), exper.CalGrad()); 241 } 242 } 243 244 } 245 246 for (Student stus : Stus) {//对每一个学生进行处理//此时学生不会重复 247 //对该学生进行处理 248 stu = stus; 249 250 //把该学生的每一个课程成绩加入课程链表之中 251 for (int j = 0; j < stu.getGrad().size(); j++) { 252 CSGrad = stu.getGrad().get(j); 253 cour = CourL.get(seaC(CSGrad.getName(), CourL)); 254 cour.getGrad().add(CSGrad.getGrad()); 255 } 256 257 //创建班级 258 k = seaCl(stu.getNum(), ClassL); 259 if (k == -1) {//班级不存在 260 int[] Cum = Arrays.copyOfRange(stu.getNum(), 0, 6); 261 ClassL.add(new Classes(Cum)); 262 k = seaCl(stu.getNum(), ClassL); 263 } 264 ClassL.get(k).getStus().add(stu);//学生加入班级 265 } 266 267 //对学号排序 268 Collections.sort(Stus); 269 270 //对课程排序 271 Comparator<Course> comparator = new Comparator<>() { 272 Collator CourLlator = Collator.getInstance(Locale.CHINA); 273 @Override 274 public int compare(Course o1, Course o2) { 275 return CourLlator.compare(o1.getName(), o2.getName()); 276 } 277 }; 278 Collections.sort(CourL, comparator); 279 280 //对班级排序 281 Collections.sort(ClassL); 282 283 //输出学生所有课程总成绩的平均分 284 for (Student v : Stus) { 285 int sum = 0; 286 int len = v.getGrad().size(); 287 for (int j = 0; j < len; j++) { 288 sum += v.getGrad().get(j).getGrad(); 289 } 290 prNum(v.getNum()); 291 if(len != 0){ 292 sum /= len; 293 pr(" " + v.getName() + " " + sum); 294 } 295 else{ 296 pr(" " + v.getName() + " did not take any exams"); 297 } 298 } 299 300 //输出课程单门课程成绩平均分 301 for (Course co : CourL) { 302 int sum = 0; 303 int a = 0, b = 0, c = 0, len = co.getGrad().size(); 304 for (int j = 0; j < len; j++) { 305 sum += co.getGrad().get(j); 306 } 307 if(len != 0){ 308 if (co.getAss().equals("考试") || co.getAss().equals("考察") ||co.getAss().equals("实验")) { 309 pr(co.getName() + " " + sum/len); 310 } 311 } 312 else{ 313 pr(co.getName() + " " + "has no grades yet"); 314 } 315 316 } 317 318 //输出班级所有课程总成绩平均分 319 for (Classes v : ClassL) { 320 int sum = 0,count = 0; 321 int len = v.getStus().size(); 322 for (int j = 0; j < len; j++) { 323 stu = v.getStus().get(j); 324 for(int l = 0;l < stu.getGrad().size();l ++){ 325 sum += stu.getGrad().get(l).getGrad(); 326 count ++; 327 } 328 } 329 prNum(v.getNum()); 330 331 if(count != 0){ 332 sum /= count; 333 pr(" " + sum); 334 } 335 else{ 336 pr(" has no grades yet"); 337 } 338 } 339 } 340 341 //查看班级是否存在 342 public static int seaCl(int[] n,ArrayList<Classes> cl){ 343 for(int i = 0;i < cl.size();i ++){ 344 n = Arrays.copyOfRange(n,0,6); 345 int[] s = Arrays.copyOfRange(cl.get(i).getNum(), 0, 6); 346 if(Arrays.equals(n,s)) { 347 return i; 348 } 349 } 350 return -1; 351 } 352 353 //查看学生是否存在 354 public static int seaS(int[] n,ArrayList<Student> s){ 355 for(int i = 0;i < s.size();i ++){ 356 int[] stu = s.get(i).getNum(); 357 if(Arrays.equals(n,stu)) { 358 return i; 359 } 360 } 361 return -1; 362 } 363 364 public static int seaTT(int[] num,String n,String coN,ArrayList<CoSe> list){ 365 //该门课程下学生的成绩不为空/即在该门课程下学生成绩存在 366 for(int i = 0;i < list.size();i ++){ 367 CoSe co = list.get(i); 368 Student s = co.getStu(); 369 if(Arrays.equals(num,s.getNum()) && n.equals(s.getName()) && coN.equals(co.getCo().getName()) && (co.getExGrad() != null || co.getExineGrad() != null || co.getExperGrad() != null)){ 370 return i; 371 } 372 } 373 return -1; 374 } 375 376 public static int seaC(String n,ArrayList<Course> list){//查找课程是否存在 377 for(int i = 0;i < list.size();i ++) { 378 if(list.get(i).getName().equals(n)) 379 return i; 380 } 381 return -1; 382 } 383 384 //输出数组数组 385 public static void prNum(int[] num){ 386 for (int i : num) System.out.print(i); 387 } 388 389 public static void prW(){ 390 pr("wrong format"); 391 } 392 393 public static void pr(String s){ 394 System.out.println(s); 395 } 396 397 } 398 399 //课程类 400 class Course { 401 private String name;//课程名字 402 private String nature;//课程性质 403 private String ass;//考核方式 404 private ArrayList<Float> ite = new ArrayList<>();//权重 405 private ArrayList<Float> grad = new ArrayList<>();//每一个学生课程成绩 406 407 public Course() { 408 } 409 410 public Course(String name, String nature, String ass) { 411 this.name = name; 412 this.nature = nature; 413 this.ass = ass; 414 } 415 416 public Course(String name, String nature, String ass, ArrayList<Float> ite) { 417 this.name = name; 418 this.nature = nature; 419 this.ass = ass; 420 this.ite = ite; 421 } 422 423 public ArrayList<Float> getIte() { 424 return ite; 425 } 426 427 public String getName() { 428 return name; 429 } 430 431 public String getNa() { 432 return nature; 433 } 434 435 public String getAss() { 436 return ass; 437 } 438 439 public ArrayList<Float> getGrad() { 440 return grad; 441 } 442 443 public boolean MathAss(String ass){//课程是否是所要求的考核方式的课程 444 return getAss().equals(ass); 445 } 446 447 public boolean MathNa(String ass){//课程是否是所要求的性质 448 return getNa().equals(ass); 449 } 450 451 public boolean isNa(String a,String b){ 452 return ((a.equals("必修") && b.equals("考试")) || a.equals("选修") && !b.equals("实验") || (a.equals("实验") && b.equals("实验"))); 453 } 454 } 455 456 class IteGrad{//分项成绩 457 private int score; 458 private float gravity; 459 460 public IteGrad() { 461 } 462 463 public IteGrad(int score, float gravity) { 464 this.score = score; 465 this.gravity = gravity; 466 } 467 468 public int getScore() { 469 return score; 470 } 471 472 public void setScore(int score) { 473 this.score = score; 474 } 475 476 public float getGravity() { 477 return gravity; 478 } 479 480 public void setGravity(float gravity) { 481 this.gravity = gravity; 482 } 483 } 484 485 //考试成绩类 486 class ExGrad{ 487 488 IteGrad[] iteGrads = new IteGrad[2]; 489 490 public ExGrad() { 491 } 492 493 public ExGrad(int usGrad, float a,int finGrad,float b) { 494 iteGrads[0] = new IteGrad(usGrad,a); 495 iteGrads[1] = new IteGrad(finGrad,b); 496 } 497 498 public float CalGrad() { 499 return (iteGrads[0].getScore() * iteGrads[0].getGravity() + iteGrads[1].getScore() * iteGrads[1].getGravity()); 500 } 501 } 502 503 //考察成绩类 504 class ExineGrad { 505 506 IteGrad[] iteGrads = new IteGrad[1]; 507 508 public ExineGrad() { 509 } 510 511 public ExineGrad(int finGrad,float b) { 512 this.iteGrads[0] = new IteGrad(finGrad,b); 513 } 514 515 public float CalGrad() { 516 return (iteGrads[0].getScore()); 517 } 518 } 519 520 //实验成绩类 521 class ExperGrad{ 522 ArrayList<IteGrad> gr = new ArrayList<>(); 523 524 public ExperGrad() { 525 } 526 527 public ExperGrad(ArrayList<Integer> exp){ 528 for(int i = 0;i < gr.size();i ++){ 529 gr.get(i).setScore(exp.get(i)); 530 } 531 } 532 533 public ExperGrad(ArrayList<Integer> exp,ArrayList<Float> ite){ 534 for(int i = 0;i < exp.size();i ++){ 535 gr.add(new IteGrad(exp.get(i), ite.get(i))); 536 } 537 538 } 539 540 public float CalGrad() { 541 float sum = 0; 542 for(IteGrad v : gr){ 543 sum += v.getScore() * v.getGravity(); 544 } 545 return sum; 546 } 547 548 public void getIte(ArrayList<Float> ite){ 549 for(int i = 0;i < gr.size();i ++){ 550 gr.get(i).setGravity(ite.get(i)); 551 } 552 } 553 } 554 555 //班级类 556 class Classes implements Comparable<Classes>{ 557 private ArrayList<Student> Stus = new ArrayList<>(); 558 private int[] num; 559 560 public Classes(int[] num) { 561 this.num = num; 562 } 563 564 public ArrayList<Student> getStus() { 565 return Stus; 566 } 567 568 public int[] getNum() { 569 return num; 570 } 571 572 public int compareTo(Classes o) { 573 int[] n = getNum(); 574 int[] c = o.getNum(); 575 int i = 0; 576 while (i < 8) { 577 if(n[i] > c[i]) return 1; 578 if(n[i] < c[i]) return -1; 579 i++; 580 } 581 return -1; 582 583 } 584 } 585 586 //学生类 587 class Student implements Comparable<Student>{ 588 private int[] num = new int[8]; 589 private String name; 590 591 //每一个是学生一门课程的成绩 592 ArrayList<CourStuGrad> grad = new ArrayList<>(); 593 594 public Student() { 595 } 596 597 public int[] getNum() { 598 return num; 599 } 600 601 public void setNum(int[] n) { 602 this.num = n; 603 } 604 605 public String getName() { 606 return name; 607 } 608 609 public void setName(String name) { 610 this.name = name; 611 } 612 613 public ArrayList<CourStuGrad> getGrad() { 614 return grad; 615 } 616 617 public void StrToInt(String s){//学号的字符串转数字数组 618 int[] arr = new int[s.length()]; 619 int i = 0; 620 while (i < arr.length) { 621 Character ch = s.charAt(i); 622 arr[i] = Integer.parseInt(ch.toString()); 623 i++; 624 } 625 setNum(arr); 626 } 627 628 public void AGrad(String name,float gr){ 629 getGrad().add(new CourStuGrad(name,gr)); 630 } 631 632 @Override 633 public int compareTo(Student o) { 634 int[] num = getNum(); 635 int[] cum = o.getNum(); 636 int i = 0; 637 while (i < 8) { 638 if(num[i] > cum[i]) return 1; 639 if(num[i] < cum[i]) return -1; 640 i++; 641 } 642 return -1; 643 } 644 } 645 646 //课程-学生成绩 647 //对于一名学生,一门课程的成绩 648 class CourStuGrad{ 649 private String name;//课程名称 650 private float grad; 651 652 public CourStuGrad(String name, float grad) { 653 this.name = name; 654 this.grad = grad; 655 } 656 657 public String getName() { 658 return name; 659 } 660 661 public float getGrad() { 662 return grad; 663 } 664 } 665 666 667 //选课 668 class CoSe{ 669 Course cour = new Course(); 670 Student stu = new Student(); 671 672 ExGrad exGrad = null; 673 ExineGrad exineGrad = null; 674 ExperGrad experGrad = null; 675 676 // AbGrad grad;//学生stu在该门课cour下的成绩grad 677 678 public CoSe() { 679 } 680 681 public void setExGrad(ExGrad exGrad) { 682 this.exGrad = exGrad; 683 } 684 685 public void setExineGrad(ExineGrad exineGrad) { 686 this.exineGrad = exineGrad; 687 } 688 689 public void setExperGrad(ExperGrad experGrad) { 690 this.experGrad = experGrad; 691 } 692 693 public ExGrad getExGrad() { 694 return exGrad; 695 } 696 697 public ExineGrad getExineGrad() { 698 return exineGrad; 699 } 700 701 public ExperGrad getExperGrad() { 702 return experGrad; 703 } 704 705 public Course getCo() { 706 return cour; 707 } 708 709 public void setCour(Course cour) { 710 this.cour = cour; 711 } 712 713 public void setStu(Student stu) { 714 this.stu = stu; 715 } 716 717 public Student getStu() { 718 return stu; 719 } 720 721 }
2.拓展题目:统计Java程序中关键词的出现次数 9-1
本次题目是作为拓展题目出现的,主要是考察了单一职责原则以及一些复杂题目设计分析。
<1> 这道题卡我卡的最久的是怎么实现各种不能被匹配上的字符串(如在多行注释中,在双引号里等等),最开始用是直接正则表达,但总有几个点过不去,后面受到同学的启发,用了replaceAll()替换匹配上的内容,一下子就找到窍门了。
原来的:
1 Pattern pS = Pattern.compile("^[A-Za-z]+");//匹配英文字符 2 Pattern p_1 = Pattern.compile("//\\S+");//注释 3 Pattern p_2 = Pattern.compile("/\\.?\\*/", Pattern.DOTALL); 4 Pattern pEnd = Pattern.compile("exit$");//结束
最后的:
isEnd(getCode().toString().replaceAll("//.*", " ").replaceAll("\".*?\"", " ").replaceAll("'.*?'", " ").replaceAll("/\\*[\\s\\S]*?\\*/", " ").replaceAll("\\s+|\\(|\\)|\\{|}|\\.|;|,|\\[|]", " ").split("[ \n]"));//判断是否输入了代码
<2> 控制行数:
这次与其他题目集最大的不用在于评分标准里有关于行数的限制和单一职责原则,因为这个要求,我真的是第一次看到我的主方法里真的只有各个方法,没有什么语句了,是一次非常不错的体验,让我意识到了这种简洁、干净利落的代码居然是我可以敲出来的,感觉以前的代码真的是乱七八糟。
代码如下:
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Game game = new Game(); 6 game.start(); 7 } 8 } 9 10 class Game{ 11 private StringBuilder code = new StringBuilder(); 12 13 private static final Set<String> key = new TreeSet<>(List.of("abstract","assert","boolean","break","byte","case","catch","char","class","const","continue","default","do","double","else","enum","extends","false","final","finally","float","for","goto","if","implements","import","instanceof","int","interface","long","native","new","null","package","private","protected","public","return","short","static","strictfp","super","switch","synchronized","this","throw","throws","transient","true","try","void","volatile","while")); 14 15 public Game() { 16 } 17 18 public StringBuilder getCode() { 19 return code; 20 } 21 22 public void setCode(StringBuilder code) { 23 this.code = code; 24 } 25 26 public void start(){ 27 sc(); 28 isEnd(getCode().toString().replaceAll("//.*", " ").replaceAll("\".*?\"", " ").replaceAll("'.*?'", " ").replaceAll("/\\*[\\s\\S]*?\\*/", " ").replaceAll("\\s+|\\(|\\)|\\{|}|\\.|;|,|\\[|]", " ").split("[ \n]"));//判断是否输入了代码 29 pr(getCode().toString().replaceAll("//.*", " ").replaceAll("\".*?\"", " ").replaceAll("'.*?'", " ").replaceAll("/\\*[\\s\\S]*?\\*/", " ").replaceAll("\\s+|\\(|\\)|\\{|}|\\.|;|,|\\[|]", " ").split("[ \n]"));//对代码进行操作并输出 30 } 31 32 public void sc(){//输入数据 33 Scanner in = new Scanner(System.in); 34 String k = "null"; 35 while (!k.equals("exit") && in.hasNextLine() ) { 36 k = in.nextLine(); 37 setCode(getCode().append(k).append("\n")); 38 } 39 } 40 41 public void isEnd(String[] o){//判断是否输入了代码 42 if(o.length == 1){ 43 System.out.println("Wrong Format"); 44 } 45 } 46 47 public void pr(String[] o){//对代码进行操作并输出 48 TreeMap<String,Integer> list = new TreeMap<>(); 49 50 for (String value : o) { 51 list.put(value, (list.get(value) != null ? list.get(value) + 1 : 1)); 52 } 53 54 for (String value : key) { 55 if(list.containsKey(value)){ 56 System.out.println(list.get(value) + "\t" + value); 57 } 58 } 59 } 60 }
三、踩坑心得
(1)课程成绩程序三次题目
在 “ 二、设计与分析 ” 中已经分析过,在这里就不再赘述。
(2)出现线程错误
如下:
这里是因为在读取的时候(9行及以后)一直使用的是nextInt()进行读取,在行末尾的时候有一个空格没有读取到,使s(17行)在获取时的调用后就会出现报错,修改后如下:
(3)普通for与增强for
如下图:
在这里person1一直不能赋值,在查阅资料后了解到增强for只能用于遍历,像赋值这些操作,则要用到普通for循环
四、改进建议
(1)单一职责问题:在经历了9-1后,感觉自己之前的代码要重新来过一遍一样,单一职责只能说有,但不多,在以后的编程中应该时刻注意单一职责,尽量是去调用方法,而不是直接写在主方法中,多思考代码设计。
(2)类设计的相关问题:在上面设计与分析课程成绩类题目时我也提到了,会设计出没有必要的类,以及对于题目了解不到位,导致设计时会出现问题,在编写时也不好下手,以后要加强练习。
(3)对比菜单和课程成绩的两个迭代,确实有课程成绩类题目比较简单的原因在,但能够感觉到因为在课程1打下的好的基础,仔细地分析了题目以及认真设计代码,让我在课程2和课程3的编写会较为顺畅,我认为这是以后在看长且复杂的题目时必须要好好维持的习惯。
(4)以及最后老生常谈的知识点学习不到位现象,像这次踩坑心得里的for循环就是一个非常典型的例子,只知其一不知其二,以后这个也是要努力改掉的坏习惯。
五、总结
1. 自我总结
(1)大的方面就如上面的改进建议
(2)其他一些细枝末节:
在这次的基本可以算的上是后半的pta作业中,我感觉我的成长是巨大的,不仅是在知识点上逐步提升的难度使我学到了许多东西,更是体会到了在我们这个整个课程时间限制下的完成任务的能力和抗压能力的提升。一个学期下来的整个pta的OOP作业,从最开始的有点放松导致菜单类等等的一些明明可以完成的更好的题目没有完美的结束掉,但是从开学到最后现在,确实是能够感觉到自己在不断进步不断前进的,虽然辛苦,但是充实。
2.对于课程的建议
(1)实验的设置:我给个人感觉实验的设置分次有一些稍稍的不平均,像最开始时间还算充裕的时候实验次数却比较少,距离期末还有一两个月的时候,实验开始密集难度也加大,我们的事情也比较多,会撞在一起。我认为在是实验前密后疏会比较好,在难度加大的后期也能够有更多时间来完成。
(2)翻转课堂:我认为翻转课堂可以更加多设置一些,不仅有趣,也能培养团队合作能力和沟通能力,极大程度的提高我们独立思考、编写复杂代码的能力。
(3)编程与实际生活联系:雨刷基本贯穿了本门课程的各个练习,我认为在以后的教学也中可以运用更多生活的方方面面的例子,做到不拘泥于书本电脑,而是实际化。
标签:OO,11,return,String,int,stu,课程,题目,public From: https://www.cnblogs.com/xyt18820189306/p/17509651.html