一.前言
PTA-7考察了菜单计价程序的迭代,主要考察类的基本结构设计,对输入字符串进行处理,对输入时间的处理,以及对输入的不同类型的菜品数据分类处理,难点在于输入数据的处理和判断输入异常,难度一般,题量少。
PTA-8考察了课程成绩统计程序的第一次,主要考察一些类基本的结构设计,一些排序的方法,字符串的处理,正则表达式的运用。难点在于输入数据的处理和判断输入异常,以及一些排序方法的重写,这是课程成绩题目的第一次的迭代,难度不大,题量少。
PTA-9考察了Java关键字的查找,正则表达式的运用,Map以及set的基本用法,以及对Map的排序。这道题目难点在于写出正确的正则表达式来快速匹配合格的关键字,提高代码的精炼度。由于有代码长度限制,要拿高分这道题目有一定难度,题量少。
PTA-10考察了HashMap的排序检索还有多态的运用,以及课程成绩录入的迭代。HashMap的检索可以通过查找Key值实现,排序可以按需求重写比较器的方法排序。课程成绩的录入考察的知识与第一次非常相似,基本没有啥变化,题目难度有一定提升,题量一般。
PTA-11考察了ArrayList的排序,比较器的重构,类实现接口,类的equal和toString方法的重写,字符串的格式化处理,组合关系的使用。这次PTA难点还是在于课程成绩录入的题目,要求使用组合关系重构之前的类结构,题目有难度,题量一般。
二.设计与分析
PTA-8
7-1 课程成绩统计程序-1
从题目所给的参考类图来看,要求设计出Class,Student,Lesson,抽象类Score等一些类,但我没有完全按照题目所给的类图来,自己新添了一些类,如用于判断输入数据的Judge类,用于存储班级的学校类,用于存储课程的课程列表类。这个题目的处理输入以及输出我都放在主类里,没有另建一个类去处理这些输入,这是比较不好的一点。在类与类之间的关系中,学生与班级是聚合关系,班级与学校也是组合关系,课程与课程列表也是聚合关系,所有类中都具有基本的私有属性。在处理输入时,选择使用正则表达式来匹配课程信息输入和课程成绩信息输入,用Judge类来判断一些异常情况,如果无误就将还会检查信息是否已存在,之后会根据是否存在来决定录入。这个题目涉及到很多排序,因为我用于存储数据都是用的ArrayList数组,所以我大多数都是通过Collections.sort()排序,在sort类中new一个Comparator自定义比较。其中一直困扰我的是课程名称的排序,我一直无法按课程名称的字符顺序输出,后来去网上找到这样的排序方法才实现了这个排序,就是重写compareTo方法,然后用 Collator.getInstance(Locale.CHINA)获得一个对象,最后返回compare比较值即可,解决了这个问题之后,这个题目才过了所有的测试点。这道题目还有一个问题就是有时候我的代码会超过最大内存导致无法提交,这里就是我在主方法设计处理输入逻辑的时候太累赘了,有一些代码非常累赘,完全可以封装成一些方法去执行。具体代码如下:1 import java.util.Scanner; 2 import java.util.regex.Pattern; 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.text.Collator; 7 import java.util.Locale; 8 9 public class Main { 10 public static void main(String[] args) { 11 Scanner scanner = new Scanner(System.in); 12 School school = new School();//用于存储班级 13 Schedule schedule = new Schedule();//用于存储课程 14 Judge judge = new Judge();//判断 15 String str = scanner.nextLine(); 16 while (true) { 17 if (str.equals("end")) { 18 break; 19 } 20 String[] strs = str.split("\\s+"); 21 if (Pattern.matches("^[\\u4e00-\\u9fa5A-Za-z]+\\s+(必修|选修)(\\s+(考试|考察))?$", str)) {//正则表达式判断输入是否为课程 22 if (!judge.check2(strs[0])) { 23 System.out.println("wrong format"); 24 } else {//添加课程 25 if (strs.length == 2) { 26 if (strs[1].equals("必修")) { 27 Lesson lesson = new Lesson(strs[0], strs[1], "考试"); 28 schedule.add(lesson); 29 } else { 30 System.out.println(strs[0] + " : course type & access mode mismatch"); 31 } 32 } else if (strs.length == 3) { 33 if (strs[1].equals("必修") && strs[2].equals("考察")) { 34 System.out.println(strs[0] + " : course type & access mode mismatch"); 35 } else { 36 if (schedule.search(strs[0]) == null) { 37 Lesson l = new Lesson(strs[0], strs[1], strs[2]); 38 schedule.add(l); 39 } 40 } 41 } 42 } 43 44 }else if (Pattern.matches("^\\d+\\s+\\S+\\s+\\S+\\s+(\\d+\\s+)?\\d+$", str)) {//课程成绩输入 45 String cID = strs[0].substring(0, 6); 46 if (!judge.check1(strs[0])||!judge.check2(strs[1])) { 47 System.out.println("wrong format"); 48 }else if (schedule.search(strs[2]) == null){//课程是否存在 49 System.out.println(strs[2]+" does not exist"); 50 if (school.getC(cID) == null) {//班级是否存在 51 Class c = new Class(cID); 52 Student stu = new Student(strs[0], strs[1]); 53 c.add(stu); 54 school.add(c); 55 }else if (school.getC(cID).search(strs[0]) == null){ 56 Student stu = new Student(strs[0], strs[1]); 57 school.getC(cID).add(stu); 58 } 59 }else if((schedule.search(strs[2]).getWay().equals("考试")&&strs.length == 4)||(schedule.search(strs[2]).getWay().equals("考察")&&strs.length == 5)){ 60 System.out.println(strs[0] + " " + strs[1] + " : access mode mismatch"); 61 if (school.getC(cID) == null) {//班级是否存在 62 Class c = new Class(cID); 63 Student stu = new Student(strs[0], strs[1]); 64 c.add(stu); 65 school.add(c); 66 } else if (school.getC(cID).search(strs[0]) == null){//学生是否存在 67 Student stu = new Student(strs[0], strs[1]); 68 school.getC(cID).add(stu); 69 } 70 }else if (strs.length == 4) {//无平时成绩 71 if (!judge.check3(strs[3])) { 72 System.out.println("wrong format"); 73 }else { 74 int fsc = Integer.parseInt(strs[3]); 75 if (school.getC(cID) == null) {//班级是否存在 76 Class c = new Class(cID); 77 Student stu = new Student(strs[0], strs[1]); 78 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 79 stu.add(sc); 80 schedule.search(strs[2]).add(stu); 81 c.add(stu); 82 school.add(c); 83 }else if (school.getC(cID).search(strs[0]) == null) {//学生是否存在 84 Student stu = new Student(strs[0], strs[1]); 85 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 86 stu.add(sc); 87 schedule.search(strs[2]).add(stu); 88 school.getC(cID).add(stu); 89 }else if (school.getC(cID).search(strs[0]).getSc(strs[2]) == null) { 90 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 91 school.getC(cID).search(strs[0]).add(sc); 92 Student stu = new Student(strs[0], strs[1]); 93 stu.add(sc); 94 schedule.search(strs[2]).add(stu); 95 } 96 } 97 }else if (strs.length == 5) {//有平时成绩,处理方式与无平时成绩大致相同 98 if (!judge.check3(strs[3]) || !judge.check3(strs[4])) { 99 System.out.println("wrong format"); 100 }else { 101 int usc = Integer.parseInt(strs[3]); 102 int fsc = Integer.parseInt(strs[4]); 103 if (school.getC(cID) == null) { 104 Class c = new Class(cID); 105 Student stu = new Student(strs[0], strs[1]); 106 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 107 stu.add(sc); 108 schedule.search(strs[2]).add(stu); 109 c.add(stu); 110 school.add(c); 111 }else if (school.getC(cID).search(strs[0]) == null) { 112 Student stu = new Student(strs[0], strs[1]); 113 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 114 stu.add(sc); 115 schedule.search(strs[2]).add(stu); 116 school.getC(cID).add(stu); 117 }else if (school.getC(cID).search(strs[0]).getSc(strs[2]) == null) { 118 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 119 school.getC(cID).search(strs[0]).add(sc); 120 Student stu = new Student(strs[0], strs[1]); 121 stu.add(sc); 122 schedule.search(strs[2]).add(stu); 123 } 124 } 125 } 126 }else {//不匹配输入格式 127 System.out.println("wrong format"); 128 } 129 str = scanner.nextLine(); 130 } 131 schedule.sort();//排序 132 school.sort(); 133 for (Class c: school.getC()){//输出学生 134 c.sort(); 135 for (Student s: c.getStus()){ 136 if(s.getSc().isEmpty()){ 137 System.out.println(s.getID()+" "+s.getName()+" did not take any exams"); 138 }else { 139 System.out.println(s.getID()+" "+s.getName()+" "+s.getAver()); 140 } 141 } 142 } 143 for (Lesson l: schedule.getLs()) {//输出课程 144 if (l.getStus().isEmpty()){ 145 System.out.println(l.getName()+" has no grades yet"); 146 }else { 147 if(l.getAver1() < 0){ 148 System.out.println(l.getName()+" "+l.getAver2()+" "+l.getAver3()); 149 }else { 150 System.out.println(l.getName()+" "+l.getAver1()+" "+l.getAver2()+" "+l.getAver3()); 151 } 152 } 153 } 154 for (Class c:school.getC()){//输出班级 155 if(c.getAver() < 0){ 156 System.out.println(c.getID()+" has no grades yet"); 157 }else { 158 System.out.println(c.getID()+" "+c.getAver()); 159 } 160 } 161 } 162 } 163 164 class Judge { 165 public boolean check1(String Id) {//检查学生ID 166 if (Pattern.matches("\\d{8}",Id)) { 167 return true; 168 } 169 return false; 170 } 171 public boolean check2(String n) {//检查名字 172 if (Pattern.matches("^[\\w\\W]{1,10}$",n)) { 173 return true; 174 } 175 return false; 176 } 177 public boolean check3(String s) {//检查分数 178 if (Pattern.matches("^([1-9]\\d?|100|0)$",s)) { 179 return true; 180 } 181 return false; 182 } 183 184 } 185 186 class School { 187 private ArrayList<Class> cla = new ArrayList<>();//班级数组 188 189 public void add(Class c) { 190 cla.add(c); 191 } 192 193 public Class getC(String ID) {//查找班级 194 for (Class c : cla) { 195 if (ID.equals(c.getID())) { 196 return c; 197 } 198 } 199 return null; 200 } 201 202 public void sort() {//排序 203 Collections.sort(cla, new Comparator<Class>() { 204 @Override 205 public int compare(Class c1, Class c2) { 206 return c1.getID().compareTo(c2.getID()); 207 } 208 }); 209 210 } 211 212 public ArrayList<Class> getC() { 213 return cla; 214 } 215 } 216 217 class Schedule{ 218 private ArrayList<Lesson> ls = new ArrayList<>();//课程数组 219 public void add(Lesson l){ 220 ls.add(l); 221 } 222 223 public Lesson search(String s){//寻找课程 224 for (Lesson lesson: ls){ 225 if(lesson.getName().equals(s)){ 226 return lesson; 227 } 228 } 229 return null; 230 } 231 232 public void sort() {//排序 233 Collections.sort(ls); 234 } 235 236 public ArrayList<Lesson> getLs() { 237 return ls; 238 } 239 } 240 241 class Student { 242 private String ID;//学生ID 243 private String name;//学生名字 244 private ArrayList<Score> scs = new ArrayList<>();//分数数组 245 246 public Student(String studentId, String name) { 247 this.ID = studentId; 248 this.name = name; 249 } 250 251 public String getID() { 252 return ID; 253 } 254 255 public String getName() { 256 return name; 257 } 258 259 public void add(Score score) { 260 scs.add(score); 261 } 262 263 public Score getSc(String name) {//查找分数 264 for (Score s : scs) { 265 if (s.getLesson().getName().equals(name)) { 266 return s; 267 } 268 } 269 return null; 270 } 271 272 public int getAver() {//取平均分 273 int sc = 0; 274 for (Score s : scs) { 275 sc += s.getScore(); 276 } 277 if(sc < 0 ||scs.size() == 0){ 278 return -1; 279 } 280 return (int) (sc / scs.size()); 281 } 282 283 public ArrayList<Score> getSc() { 284 return scs; 285 } 286 } 287 288 class Score { 289 private Lesson lesson;//课程 290 private int u = -1;//平时 291 private int f = -1;//期末 292 private int total = 0;//总分 293 294 public int getU() { 295 return u; 296 } 297 298 public int getF() { 299 return f; 300 } 301 302 public Score(Lesson l, int u, int f) { 303 this.lesson = l; 304 this.u = u; 305 this.f = f; 306 } 307 308 public Lesson getLesson() { 309 return lesson; 310 } 311 312 public int getScore() {//算总分 313 if (u != -1) { 314 total = (int) (u * 0.3 + f * 0.7); 315 } else { 316 total = f; 317 } 318 return total; 319 } 320 } 321 322 class Class { 323 324 private String ID;//班号 325 private ArrayList<Student> stus = new ArrayList<>();//学生数组 326 public Class(String ID) { 327 this.ID = ID; 328 } 329 330 public void add(Student s) { 331 stus.add(s); 332 } 333 public String getID() { 334 return ID; 335 } 336 337 public Student search(String studentID) {//查找学生 338 for (Student s : 339 stus) { 340 if (s.getID().equals(studentID)) { 341 return s; 342 } 343 } 344 return null; 345 } 346 public int getAver(){//求平均分 347 int sc = 0; 348 for (Student s: stus) { 349 sc += s.getAver(); 350 } 351 if (sc < 0){ 352 return -1; 353 } 354 return (int)(sc/ stus.size()); 355 } 356 public void sort(){//排序 357 Collections.sort(stus, new Comparator<Student>() { 358 @Override 359 public int compare(Student s1, Student s2) { 360 return s1.getID().compareTo(s2.getID()); 361 } 362 }); 363 } 364 public ArrayList<Student> getStus() { 365 return stus; 366 } 367 } 368 class Lesson implements Comparable<Lesson> { 369 private String name;//课程名字 370 private String trait;//课程性质 371 private String way;//考核方式 372 private ArrayList<Student> stus = new ArrayList<>();//学生数组 373 374 public Lesson(String n, String t, String w) { 375 this.name = n; 376 this.trait = t; 377 this.way = w; 378 } 379 380 public String getName() { 381 return name; 382 } 383 384 public String getWay() { 385 return way; 386 } 387 388 public void add(Student s) { 389 stus.add(s); 390 } 391 392 public ArrayList<Student> getStus() { 393 return stus; 394 } 395 396 public int getAver1(){//求平时 397 int sc = 0; 398 for (Student s: stus){ 399 sc += s.getSc().get(0).getU(); 400 } 401 return (int)(sc/ stus.size()); 402 } 403 public int getAver2(){//求期末 404 int sc = 0; 405 for (Student s: stus){ 406 sc += s.getSc().get(0).getF(); 407 } 408 return (int)(sc/ stus.size()); 409 } 410 411 public int getAver3(){//求总分 412 int sc = 0; 413 for (Student s: stus){ 414 sc += s.getSc().get(0).getScore(); 415 } 416 return (int)(sc/ stus.size()); 417 } 418 419 @Override 420 public int compareTo(Lesson l) { 421 Comparator<Object> c = Collator.getInstance(Locale.CHINA); 422 return ((Collator) c).compare(this.name,l.getName()); 423 } 424 }View Code
PTA-9
7-1 统计Java程序中关键词的出现次数
这道题目我用的方法是先将代码中的注释和字符串先去除,在进行Java关键字的查找。将所有的Java关键字存在hashSet中,先将从控制台输入的代码存储到一个字符串中,构建一个static的方法来执行去除代码中的字符串和注释,在主方法调用remove房后再进行查找。构建一个正则表达式来匹配所有的hashset关键字,将匹配到的关键字存入有序的treemap中,用关键字作为键值,关键字的数量作为Value值来进行统计,最后用foreach循环输出即可,代码如下:
1 import java.util.*; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 5 public class Main { 6 7 // Java关键字集合 8 private static final Set<String> KEYWORDS = new HashSet<>(Arrays.asList("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "if", "goto", "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")); 9 10 public static void main(String[] args) { 11 Scanner scanner = new Scanner(System.in); 12 // 读取输入的源码 13 StringBuilder builder = new StringBuilder(); 14 while (scanner.hasNextLine()) { 15 String line = scanner.nextLine(); 16 if ("exit".equals(line)) { 17 break; 18 } 19 builder.append(line).append('\n'); 20 } 21 String str = builder.toString(); 22 if (str.isEmpty()){ 23 System.out.println("Wrong Format"); 24 System.exit(0); 25 } 26 Map<String, Integer> keywordCountMap = new TreeMap<>(); // 使用TreeMap按照键值排序 27 String regex = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; // 构建正则表达式 28 String[] codeLines = remove(builder).split("\n"); 29 for (String line : codeLines) { 30 line = line.replaceAll("=","1"); 31 String[] words = line.split("\\W+"); // 非单词字符作为分隔符 32 for (String word : words) { 33 if (word.matches(regex)) { 34 keywordCountMap.merge(word, 1, Integer::sum); // merge合并key的数量 35 } 36 } 37 } 38 keywordCountMap.forEach((key, integer) -> { // 输出统计结果 39 System.out.println(integer + "\t" + key); 40 }); 41 } 42 43 public static String remove(StringBuilder builder){ 44 Pattern pattern = Pattern.compile("/\\*.*?\\*/",Pattern.DOTALL);//去除多行注释 45 Matcher matcher = pattern.matcher(builder); 46 StringBuilder code = new StringBuilder(); 47 int startIdx = 0; 48 while(matcher.find()){ 49 code.append(builder.substring(startIdx,matcher.start())); 50 startIdx = matcher.end(); 51 } 52 code.append(builder.substring(startIdx)); 53 pattern = Pattern.compile("\".*?\"|\\/\\/.*");//去除单行注释和字符串 54 matcher = pattern.matcher(code); 55 String result = matcher.replaceAll(""); 56 return result; 57 } 58 59 }View Code
PTA-10
这次题目是课程成绩录入的迭代,新增了实验课信息的录入和实验成绩的输出,也是使用正则表达式来匹配,但那时我不会写同时匹配三种输入的正则表达式,所以就另给实验课程信息和实验课程成绩输入新开了if-else分支,这是非常愚蠢的,导致代码非常冗杂,重复了许多代码。实验课的成绩计算方法也是求各个分数平均值,计算方法也是不用修改。总体来讲类结构以及类与类之间的关系讲和第一次没有很大的改变。我保留了之前的代码很大一部分,新增了对实验课程信息的录入的处理方式和实验成绩的输入处理方式,以及Judge类新增了一些异常判断,其他的就没有什么变化。但我的代码可能之前就存在问题,导致PTA测试点会有一个非零返回,也就是出现了报错导致程序无法运行,而后也一直在用测试点去测,也没有发现问题,总之之前的设计就有问题,没有完全按照题目所给类图去设计。具体代码如下:
1 import java.util.Arrays; 2 import java.util.Scanner; 3 import java.util.regex.Pattern; 4 import java.util.ArrayList; 5 import java.util.Collections; 6 import java.util.Comparator; 7 import java.util.Locale; 8 import java.text.Collator; 9 10 public class Main { 11 public static void main(String[] args) { 12 Scanner scanner = new Scanner(System.in); 13 School school = new School();//用于存储班级 14 Schedule schedule = new Schedule();//用于存储课程 15 Judge judge = new Judge();//判断 16 String str = scanner.nextLine(); 17 while (true) { 18 if (str.equals("end")) { 19 break; 20 } 21 String[] strs = str.split("\\s+"); 22 if (Pattern.matches("^\\S+ +(必修|选修|实验)( +(考试|考察|实验))?$", str)) {//正则表达式判断输入是否为课程 23 if (!judge.check2(strs[0])) { 24 System.out.println("wrong format"); 25 } else {//添加课程 26 if (strs.length == 2) { 27 if (strs[1].equals("必修")) { 28 Lesson lesson = new Lesson(strs[0], strs[1], "考试"); 29 schedule.add(lesson); 30 } else if (strs[1].equals("实验")) { 31 Lesson lesson = new Lesson(strs[0], strs[1], "实验"); 32 schedule.add(lesson); 33 } else { 34 System.out.println(strs[0] + " : course type & access mode mismatch"); 35 } 36 } else if (strs.length == 3) { 37 if ((strs[1].equals("必修") && !strs[2].equals("考试")) || (strs[1].equals("实验") && !strs[2].equals("实验"))) { 38 System.out.println(strs[0] + " : course type & access mode mismatch"); 39 } else { 40 if (schedule.search(strs[0]) == null) { 41 Lesson l = new Lesson(strs[0], strs[1], strs[2]); 42 schedule.add(l); 43 } 44 } 45 } 46 } 47 48 } else if (Pattern.matches("^\\d+ +\\S+ +\\S+ +(\\d+\\s+)?\\d+$", str)) {//课程成绩输入 49 String cID = strs[0].substring(0, 6); 50 if (!judge.check1(strs[0]) || !judge.check2(strs[1])) { 51 System.out.println("wrong format"); 52 } else if (schedule.search(strs[2]) == null) {//课程是否存在 53 System.out.println(strs[2] + " does not exist"); 54 add(school, strs, cID,schedule); 55 } else if ((schedule.search(strs[2]).getWay().equals("考试") && strs.length == 4) || (schedule.search(strs[2]).getWay().equals("考察") && strs.length == 5)) { 56 System.out.println(strs[0] + " " + strs[1] + " : access mode mismatch"); 57 add(school, strs, cID,schedule); 58 } else if (strs.length == 4) {//无平时成绩 59 if (!judge.check3(strs[3])) { 60 System.out.println("wrong format"); 61 } else { 62 int fsc = Integer.parseInt(strs[3]); 63 if (school.getC(cID) == null) {//班级是否存在 64 Class c = new Class(cID); 65 Student stu = new Student(strs[0], strs[1]); 66 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 67 stu.add(sc); 68 schedule.search(strs[2]).add(stu); 69 c.add(stu); 70 school.add(c); 71 } else if (school.getC(cID).search(strs[0]) == null) {//学生是否存在 72 Student stu = new Student(strs[0], strs[1]); 73 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 74 stu.add(sc); 75 schedule.search(strs[2]).add(stu); 76 school.getC(cID).add(stu); 77 } else if (school.getC(cID).search(strs[0]).getSc(strs[2]) == null) { 78 Score sc = new Score(schedule.search(strs[2]), -1, fsc); 79 school.getC(cID).search(strs[0]).add(sc); 80 Student stu = new Student(strs[0], strs[1]); 81 stu.add(sc); 82 schedule.search(strs[2]).add(stu); 83 } 84 } 85 } else if (strs.length == 5) {//有平时成绩,处理方式与无平时成绩大致相同 86 if (!judge.check3(strs[3]) || !judge.check3(strs[4])) { 87 System.out.println("wrong format"); 88 } else { 89 int usc = Integer.parseInt(strs[3]); 90 int fsc = Integer.parseInt(strs[4]); 91 if (school.getC(cID) == null) { 92 Class c = new Class(cID); 93 Student stu = new Student(strs[0], strs[1]); 94 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 95 stu.add(sc); 96 schedule.search(strs[2]).add(stu); 97 c.add(stu); 98 school.add(c); 99 } else if (school.getC(cID).search(strs[0]) == null) { 100 Student stu = new Student(strs[0], strs[1]); 101 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 102 stu.add(sc); 103 schedule.search(strs[2]).add(stu); 104 school.getC(cID).add(stu); 105 } else if (school.getC(cID).search(strs[0]).getSc(strs[2]) == null) { 106 Score sc = new Score(schedule.search(strs[2]), usc, fsc); 107 school.getC(cID).search(strs[0]).add(sc); 108 Student stu = new Student(strs[0], strs[1]); 109 stu.add(sc); 110 schedule.search(strs[2]).add(stu); 111 } 112 } 113 } 114 } else if (Pattern.matches("^\\d+ \\S+ \\S+ \\d+(?: \\d+)+$", str)) { 115 String cID = strs[0].substring(0, 6); 116 if (!judge.checkNum(strs[3])) { 117 System.out.println("wrong format"); 118 } else if (strs.length != Integer.parseInt(strs[3]) + 4) { 119 System.out.println(strs[0]+" "+strs[1]+" : access mode mismatch"); 120 add(school, strs, cID,schedule); 121 }else if (!judge.check(Arrays.copyOfRange(strs,4,strs.length))){ 122 System.out.println("wrong format"); 123 }else { 124 if (school.getC(cID) == null) { 125 Class c = new Class(cID); 126 Student stu = new Student(strs[0], strs[1]); 127 Score sc = new Score(schedule.search(strs[2])); 128 sc.add(Arrays.copyOfRange(strs,4,strs.length)); 129 stu.add(sc); 130 schedule.search(strs[2]).add(stu); 131 c.add(stu); 132 school.add(c); 133 } else if (school.getC(cID).search(strs[0]) == null) { 134 Student stu = new Student(strs[0], strs[1]); 135 Score sc = new Score(schedule.search(strs[2])); 136 sc.add(Arrays.copyOfRange(strs,4,strs.length)); 137 stu.add(sc); 138 schedule.search(strs[2]).add(stu); 139 school.getC(cID).add(stu); 140 } else if (school.getC(cID).search(strs[0]).getSc(strs[2]) == null) { 141 Score sc = new Score(schedule.search(strs[2])); 142 sc.add(Arrays.copyOfRange(strs,4,strs.length)); 143 school.getC(cID).search(strs[0]).add(sc); 144 Student stu = new Student(strs[0], strs[1]); 145 stu.add(sc); 146 schedule.search(strs[2]).add(stu); 147 } 148 } 149 150 } else {//不匹配输入格式 151 System.out.println("wrong format"); 152 } 153 str = scanner.nextLine(); 154 } 155 schedule.sort();//排序 156 school.sort(); 157 for (Class c : school.getC()) {//输出学生 158 c.sort(); 159 for (Student s : c.getStus()) { 160 if (s.getSc().isEmpty()) { 161 System.out.println(s.getID() + " " + s.getName() + " did not take any exams"); 162 } else { 163 System.out.println(s.getID() + " " + s.getName() + " " + s.getAver()); 164 } 165 } 166 } 167 for (Lesson l : schedule.getLs()) {//输出课程 168 int flag = 1; 169 for (Student s:l.getStus()){ 170 if (!s.getSc().isEmpty()){ 171 flag = 0; 172 break; 173 } 174 } 175 if (flag == 1) { 176 System.out.println(l.getName() + " has no grades yet"); 177 } else if (l.getWay().equals("实验")) { 178 System.out.println(l.getName() + " " + l.getAver3()); 179 } else if (l.getWay().equals("考察")) { 180 System.out.println(l.getName() + " " + l.getAver2() + " " + l.getAver3()); 181 } else { 182 System.out.println(l.getName() + " " + l.getAver1() + " " + l.getAver2() + " " + l.getAver3()); 183 } 184 } 185 for (Class c : school.getC()) {//输出班级 186 if (c.getAver() < 0) { 187 System.out.println(c.getID() + " has no grades yet"); 188 } else { 189 System.out.println(c.getID() + " " + c.getAver()); 190 } 191 } 192 } 193 194 static void add(School school, String[] strs, String cID,Schedule schedule) { 195 if (school.getC(cID) == null) {//班级是否存在 196 Class c = new Class(cID); 197 Student stu = new Student(strs[0], strs[1]); 198 if (schedule.search(strs[2])!=null){ 199 schedule.search(strs[2]).add(stu); 200 } 201 c.add(stu); 202 school.add(c); 203 } else if (school.getC(cID).search(strs[0]) == null) { 204 Student stu = new Student(strs[0], strs[1]); 205 school.getC(cID).add(stu); 206 if (schedule.search(strs[2])!=null){ 207 schedule.search(strs[2]).add(stu); 208 } 209 } 210 } 211 } 212 213 class Judge { 214 public boolean check1(String Id) {//检查学生ID 215 return Pattern.matches("\\d{8}", Id); 216 } 217 218 public boolean check2(String n) {//检查名字 219 return Pattern.matches("^[\\w\\W]{1,10}$", n); 220 } 221 222 public boolean check3(String s) {//检查分数 223 return Pattern.matches("^([1-9]\\d?|100|0)$", s); 224 } 225 226 public boolean checkNum(String s) {//检查实验次数 227 return Integer.parseInt(s) > 3 && Integer.parseInt(s) < 10; 228 } 229 public boolean check(String[] strings){//检查分数是否合法 230 for (String s:strings){ 231 if (!Pattern.matches("^([1-9]\\d?|100|0)$",s)){ 232 return false; 233 } 234 } 235 return true; 236 } 237 } 238 class School { 239 private ArrayList<Class> cla = new ArrayList<>();//班级数组 240 241 public void add(Class c) { 242 cla.add(c); 243 } 244 245 public Class getC(String ID) {//查找班级 246 for (Class c : cla) { 247 if (ID.equals(c.getID())) { 248 return c; 249 } 250 } 251 return null; 252 } 253 254 public void sort() {//排序 255 Collections.sort(cla, new Comparator<Class>() { 256 @Override 257 public int compare(Class c1, Class c2) { 258 return c1.getID().compareTo(c2.getID()); 259 } 260 }); 261 262 } 263 264 public ArrayList<Class> getC() { 265 return cla; 266 } 267 } 268 class Schedule{ 269 private ArrayList<Lesson> ls = new ArrayList<>();//课程数组 270 public void add(Lesson l){ 271 ls.add(l); 272 } 273 274 public Lesson search(String s){//寻找课程 275 for (Lesson lesson: ls){ 276 if(lesson.getName().equals(s)){ 277 return lesson; 278 } 279 } 280 return null; 281 } 282 283 public void sort() {//排序 284 Collections.sort(ls); 285 } 286 287 public ArrayList<Lesson> getLs() { 288 return ls; 289 } 290 } 291 class Student { 292 private String ID;//学生ID 293 private String name;//学生名字 294 private ArrayList<Score> scs = new ArrayList<>();//分数数组 295 296 public Student(String studentId, String name) { 297 this.ID = studentId; 298 this.name = name; 299 } 300 301 public String getID() { 302 return ID; 303 } 304 305 306 public String getName() { 307 return name; 308 } 309 310 public void add(Score score) { 311 scs.add(score); 312 } 313 314 public Score getSc(String name) {//查找分数 315 for (Score s : scs) { 316 if (s.getLesson().getName().equals(name)) { 317 return s; 318 } 319 } 320 return null; 321 } 322 323 public int getAver() {//取平均分 324 int sc = 0; 325 for (Score s : scs) { 326 if (s.getScore() != -1) { 327 sc += s.getScore(); 328 } 329 } 330 if (sc < 0 || scs.size() == 0) { 331 return 0; 332 } 333 return (sc / scs.size()); 334 } 335 336 public ArrayList<Score> getSc() { 337 return scs; 338 } 339 } 340 class Score { 341 private Lesson lesson;//课程 342 private int u = 0;//平时 343 private int f = 0;//期末 344 private ArrayList<Integer> grade = new ArrayList<>(); 345 346 public int getU() { 347 return u; 348 } 349 350 public int getF() { 351 return f; 352 } 353 354 355 public Score(Lesson l, int u, int f) { 356 this.lesson = l; 357 this.u = u; 358 this.f = f; 359 } 360 361 public Score(Lesson l) { 362 this.lesson = l; 363 } 364 365 public void add(String[] str) { 366 for (String s : str) { 367 grade.add(Integer.parseInt(s)); 368 } 369 } 370 371 public Lesson getLesson() { 372 return lesson; 373 } 374 375 public int getScore() {//算总分 376 int score = 0; 377 if (lesson.getWay().equals("考试")) { 378 score = (int) (0.3 * u + 0.7 * f); 379 } else if (lesson.getWay().equals("考察")) { 380 score = f; 381 } else { 382 if (grade.isEmpty()) { 383 score = 0; 384 } else { 385 for (int i : grade) { 386 score += i; 387 } 388 score = (score / grade.size()); 389 } 390 391 } 392 return score; 393 } 394 } 395 class Class { 396 397 private String ID;//班号 398 private ArrayList<Student> stus = new ArrayList<>();//学生数组 399 public Class(String ID) { 400 this.ID = ID; 401 } 402 403 public void add(Student s) { 404 stus.add(s); 405 } 406 public String getID() { 407 return ID; 408 } 409 410 public Student search(String studentID) {//查找学生 411 for (Student s : 412 stus) { 413 if (s.getID().equals(studentID)) { 414 return s; 415 } 416 } 417 return null; 418 } 419 public int getAver(){//求平均分 420 int sc = 0,flag = 1; 421 for (Student s:stus){ 422 if (!s.getSc().isEmpty()){ 423 flag = 0; 424 break; 425 } 426 } 427 if (flag == 0){ 428 for (Student s: stus) { 429 sc += s.getAver(); 430 } 431 }else { 432 return -1; 433 } 434 return (sc/ stus.size()); 435 } 436 public void sort(){//排序 437 Collections.sort(stus, new Comparator<Student>() { 438 @Override 439 public int compare(Student s1, Student s2) { 440 return s1.getID().compareTo(s2.getID()); 441 } 442 }); 443 } 444 public ArrayList<Student> getStus() { 445 return stus; 446 } 447 } 448 class Lesson implements Comparable<Lesson> { 449 private String name;//课程名字 450 private String trait;//课程性质 451 private String way;//考核方式 452 private ArrayList<Student> stus = new ArrayList<>();//学生数组 453 454 public Lesson(String n, String t, String w) { 455 this.name = n; 456 this.trait = t; 457 this.way = w; 458 } 459 460 public String getName() { 461 return name; 462 } 463 464 public String getWay() { 465 return way; 466 } 467 468 public void add(Student s) { 469 stus.add(s); 470 } 471 472 public ArrayList<Student> getStus() { 473 return stus; 474 } 475 476 public int getAver1() {//求平时 477 int sc = 0; 478 for (Student s : stus) { 479 if (!s.getSc().isEmpty()) { 480 sc += s.getSc().get(0).getU(); 481 } 482 } 483 return (sc / stus.size()); 484 } 485 486 public int getAver2() {//求期末 487 int sc = 0; 488 for (Student s : stus) { 489 if (!s.getSc().isEmpty()){ 490 sc += s.getSc().get(0).getF(); 491 } 492 } 493 return (sc / stus.size()); 494 } 495 496 public int getAver3() {//求总分 497 int sc = 0; 498 for (Student s : stus) { 499 if (!s.getSc().isEmpty()) { 500 sc += s.getSc().get(0).getScore(); 501 } 502 } 503 return (sc / stus.size()); 504 } 505 506 @Override 507 public int compareTo(Lesson l) { 508 Comparator<Object> c = Collator.getInstance(Locale.CHINA); 509 return ((Collator) c).compare(this.name, l.getName()); 510 } 511 }View Code
PTA-11
7-2 课程成绩统计程序-3
这次题目要求修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。考试课和实验课信息的输入有一些变化,要求输入每一项成绩的权重比,进行计算单个成绩的计算方法也有一些变化。在原来的类结构上新增了ItemScore类和LessonScore类,用于存储课程成绩,其中ItemScore组合LessonScore,处理输入输出还是在主类里面完成,同时应题目要求,计算单个成绩时,分项成绩乘以权重后要保留小数位,计算总成绩时,累加所有分项成绩的权重分以后,再去掉小数位。学生总成绩/整个班/课程平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。由于类结构的改变,这样的计算成绩的方法是比较容易实现的。同时,题目不再要求输出课程的平时分,和期末分,所以在原来的Lesson类中,去除了求这一部分的方法。除此之外,Schedule类存储的也不是Lesson类,而是LessonScore类,Judge类(判断类)也新增了判断权重比和是否为一的方法,这些便是相较于之前的类结构不同之处。具体代码如下:
import java.util.Arrays; import java.util.Scanner; import java.util.regex.Pattern; import java.util.ArrayList; import java.util.Comparator; import java.util.Locale; import java.text.Collator; import java.util.Collections; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); School school = new School();//用于存储班级 Schedule schedule = new Schedule();//用于存储课程 Judge judge = new Judge();//判断 String str = scanner.nextLine(); while (true) { if (str.equals("end")) { break; } String[] strs = str.split("\\s+"); if (Pattern.matches("^(.+)\\s+(必修|选修|实验)\\s+(考试|考察|实验)(\\s+(\\d+\\.\\d+)\\s+(\\d+\\.\\d+))?|^(.+)\\s+实验\\s+实验\\s+(\\d+)((\\s+\\d+\\.\\d+)+)$", str)) {//正则表达式判断输入是否为课程 if (!judge.check2(strs[0])) { System.out.println("wrong format"); } else {//添加课程 if (strs.length == 3) { if (!strs[2].equals("考察")) {//考察课程成绩添加 System.out.println(strs[0] + " : course type & access mode mismatch"); } else if (schedule.search(strs[0]) == null) { Lesson l = new Lesson(strs[0], strs[1], strs[2]); LessonScore score = new LessonScore(l); score.add(new ItemScore(1)); schedule.add(score); } } else if (strs.length == 5) { if (!strs[2].equals("考试")) {//考试课程成绩添加 System.out.println(strs[0] + " : course type & access mode mismatch"); } else if (Double.parseDouble(strs[3]) + Double.parseDouble(strs[4]) != 1) { System.out.println(strs[0] + " : weight value error"); } else if (schedule.search(strs[0]) == null) { Lesson l = new Lesson(strs[0], strs[1], strs[2]); LessonScore score = new LessonScore(l); score.setWeight(Arrays.copyOfRange(strs, 3, 5)); schedule.add(score); } } else if (strs.length > 5) { if (!strs[2].equals("实验")) {//实验课程成绩添加 System.out.println(strs[0] + " : course type & access mode mismatch"); } else if (!judge.checkNum(strs[3])){ System.out.println("wrong format"); }else if (Integer.parseInt(strs[3]) != strs.length-4) { System.out.println(strs[0] + " : number of scores does not match"); }else if (!judge.check4(Arrays.copyOfRange(strs, 4, strs.length))){ System.out.println(strs[0] + " : weight value error"); } else if (schedule.search(strs[0]) == null) { Lesson l = new Lesson(strs[0], strs[1], strs[2]); LessonScore score = new LessonScore(l); score.setWeight(Arrays.copyOfRange(strs, 4, strs.length)); schedule.add(score); } } } } else if (Pattern.matches("(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+((\\d+\\s*)+|(\\b\\w+\\b\\s*\\d*\\s*)*)", str)) {//课程成绩输入 String cID = strs[0].substring(0, 6); if (!judge.check1(strs[0]) || !judge.check2(strs[1])) {//检查学号姓名 System.out.println("wrong format"); } else if (schedule.search(strs[2]) == null) {//课程是否存在 System.out.println(strs[2] + " does not exist"); add(school, strs, cID); } else if (schedule.search(strs[2]).getlesson().getWay().equals("考察")) {//考察成绩录入 if (strs.length != 4) {//输入不匹配 System.out.println(strs[0] + " " + strs[1] + " : access mode mismatch"); add(school, strs, cID); } else if (!judge.check3(strs[3])) {//分数超限 System.out.println("wrong format"); } else {//成绩录入 Student student = new Student(strs[0], strs[1]); LessonScore score = new LessonScore(schedule.search(strs[2]).getlesson(),add(schedule,strs)); score.setScore(Arrays.copyOfRange(strs,3,4)); if (school.getC(cID) == null) { Class c = new Class(cID); student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); c.add(student); school.add(c); } else if (school.getC(cID).search(strs[0]) == null) { student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); school.getC(cID).add(student); } else if (school.getC(cID).search(strs[0]).getSc(strs[3]) == null) { school.getC(cID).search(strs[0]).add(score); schedule.search(strs[2]).setScore(Arrays.copyOfRange(strs, 3, 4)); } } } else if (schedule.search(strs[2]).getlesson().getWay().equals("考试")) {//考试成绩录入,大致同上 if (strs.length != 5){ System.out.println(strs[0] + " " + strs[1] + " : access mode mismatch"); add(school, strs, cID); } else if (!judge.check3(strs[3]) || !judge.check3(strs[4])) { System.out.println("wrong format"); } else { LessonScore score = new LessonScore(schedule.search(strs[2]).getlesson(),add(schedule,strs)); score.setScore(Arrays.copyOfRange(strs, 3, 5)); Student student = new Student(strs[0], strs[1]); if (school.getC(cID) == null) { Class c = new Class(cID); student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); c.add(student); school.add(c); } else if (school.getC(cID).search(strs[0]) == null) { student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); school.getC(cID).add(student); } else if (school.getC(cID).search(strs[0]).getSc(strs[3]) == null) { school.getC(cID).search(strs[0]).add(score); schedule.search(strs[2]).setScore(Arrays.copyOfRange(strs, 3, 5)); } } } else if (schedule.search(strs[2]).getlesson().getWay().equals("实验")) { if (schedule.search(strs[2]).getList().size() != strs.length - 3) { System.out.println( strs[0]+" "+strs[1]+" : access mode mismatch"); add(school, strs, cID); } else if (!judge.check(Arrays.copyOfRange(strs, 3, strs.length))) { System.out.println("wrong format"); } else { LessonScore score = new LessonScore(schedule.search(strs[2]).getlesson(),add(schedule,strs)); score.setScore(Arrays.copyOfRange(strs, 3, strs.length)); Student student = new Student(strs[0], strs[1]); if (school.getC(cID) == null) { Class c = new Class(cID); student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); c.add(student); school.add(c); } else if (school.getC(cID).search(strs[0]) == null) { student.add(score); Student s = new Student(strs[0],strs[1]); s.add(score); schedule.search(strs[2]).add(s); school.getC(cID).add(student); } else if (school.getC(cID).search(strs[0]).getSc(strs[3]) == null) { school.getC(cID).search(strs[0]).add(score); schedule.search(strs[2]).setScore(Arrays.copyOfRange(strs, 3, strs.length)); } } } } else {//不匹配输入格式 System.out.println("wrong format"); } str = scanner.nextLine(); } school.sort();//排序 schedule.sort(); for (Class c : school.getC()) {//输出学生信息 c.sort(); for (Student s : c.getStus()) { if (s.getSc().isEmpty()) { System.out.println(s.getID() + " " + s.getName() + " did not take any exams"); } else { System.out.println(s.getID() + " " + s.getName() + " " + s.getAver()); } } } for (LessonScore l : schedule.getLs()) {//输出课程信息 if (!l.judge()) { System.out.println(l.getlesson().getName() + " has no grades yet"); } else { System.out.println(l.getlesson().getName() + " " + l.getAver()); } } for (Class c : school.getC()) {//输出班级信息 if (!c.judge()) { System.out.println(c.getID() + " has no grades yet"); } else { System.out.println(c.getID() +" "+ c.getAver()); } } } private static void add(School school, String[] strs, String cID) {//错误成绩信息的录入 if (school.getC(cID) == null){ Student stu =new Student(strs[0],strs[1]); Class c = new Class(cID); c.add(stu); school.add(c); }else if (school.getC(cID).search(strs[0]) == null){ Student stu = new Student(strs[0],strs[1]); school.getC(cID).add(stu); } } public static ArrayList<ItemScore> add(Schedule schedule,String[] strs){ ArrayList<ItemScore> list = new ArrayList<>(); for (ItemScore i:schedule.search(strs[2]).getList()){ list.add(new ItemScore(i.getWeight())); } return list; } } class ItemScore { private ArrayList<Double> score = new ArrayList<>();//分数 private double weight;//权重 public ItemScore(double weight) { this.weight = weight; } public void add(double s){ score.add(s); } public double getTotal(){//算分 double sc = 0; for (Double s:score){ sc+=s*weight; } return sc/score.size(); } public double getWeight() { return weight; } public ArrayList<Double> getScore() { return score; } } class LessonScore implements Comparable<LessonScore>{ private Lesson lesson;//课程 private ArrayList<Student> students = new ArrayList<>();//学生数组 private ArrayList<ItemScore> list = new ArrayList<>();//分项成绩 public LessonScore(Lesson lesson) { this.lesson = lesson; } public LessonScore(Lesson lesson, ArrayList<ItemScore> list) { this.lesson = lesson; this.list = list; } public Lesson getlesson() { return lesson; } public void setWeight(String[] str) {//设置权重 for (int i = 0; i < str.length; i++) { list.add(new ItemScore(Double.parseDouble(str[i]))); } } public void add(ItemScore score) {//添加分项成绩 list.add(score); } public ArrayList<ItemScore> getList() { return list; } public void setScore(String[] str) {//设置成绩 for (int i = 0; i < list.size(); i++) { list.get(i).add(Double.parseDouble(str[i])); } } public boolean judge(){//判断课程是否有成绩 for (Student s:students){ if (!s.getSc().isEmpty()){ return true; } } return false; } public int getTotal() {//算总分 double score = 0; for (ItemScore i : list) { score +=i.getTotal(); } return (int)score; } public void add(Student s){ students.add(s); } public int getAver(){//算平均分 int score = 0; for (Student s:students){ score+=s.getAver(); } return score/students.size(); } @Override public int compareTo(LessonScore l) {//按课程名称排序 Comparator<Object> c = Collator.getInstance(Locale.CHINA); return ((Collator) c).compare(this.lesson.getName(), l.getlesson().getName()); } } class Judge { public boolean check1(String Id) {//检查学生ID return Pattern.matches("\\d{8}", Id); } public boolean check2(String n) {//检查名字 return Pattern.matches("^[\\w\\W]{1,10}$", n); } public boolean check3(String s) {//检查分数 return Pattern.matches("^([1-9]\\d?|100|0)$", s); } public boolean check(String[] strings) {//检查分数是否合法 for (String s : strings) { if (!Pattern.matches("^([1-9]\\d?|100|0)$", s)) { return false; } } return true; } public boolean check4(String[] str) {//检查权重和是否为一 double sum = 0; for (String s : str) { sum += Double.parseDouble(s); } if (sum < 1.01 && sum > 0.99) { return true; } return false; } public boolean checkNum(String s) { return Integer.parseInt(s) > 3 && Integer.parseInt(s) < 10; } } class School { private ArrayList<Class> cla = new ArrayList<>();//班级数组 public void add(Class c) { cla.add(c); } public Class getC(String ID) {//查找班级 for (Class c : cla) { if (ID.equals(c.getID())) { return c; } } return null; } public void sort() {//排序 Collections.sort(cla, new Comparator<Class>() { @Override public int compare(Class c1, Class c2) { return c1.getID().compareTo(c2.getID()); } }); } public ArrayList<Class> getC() { return cla; } } class Schedule{ private ArrayList<LessonScore> ls = new ArrayList<>();//课程成绩数组 public void add(LessonScore l){ ls.add(l); } public LessonScore search(String s){//寻找课程 for (LessonScore l: ls){ if(l.getlesson().getName().equals(s)){ return l; } } return null; } public void sort() {//排序 Collections.sort(ls); } public ArrayList<LessonScore> getLs() { return ls; } } class Student { private String ID;//学生ID private String name;//学生名字 private ArrayList<LessonScore> scs = new ArrayList<>();//分数数组 public Student(String studentId, String name) { this.ID = studentId; this.name = name; } public String getID() { return ID; } public String getName() { return name; } public void add(LessonScore score) { scs.add(score); } public LessonScore getSc(String name) {//查找分数 return null; } public int getAver() {//取平均分 int score = 0; for (LessonScore s:scs){ score+=s.getTotal(); } if (scs.isEmpty()){ return 0; } return score/scs.size(); } public ArrayList<LessonScore> getSc() { return scs; } } class Class { private String ID;//班号 private ArrayList<Student> stus = new ArrayList<>();//学生数组 public Class(String ID) { this.ID = ID; } public void add(Student s) { stus.add(s); } public String getID() { return ID; } public Student search(String studentID) {//查找学生 for (Student s : stus) { if (s.getID().equals(studentID)) { return s; } } return null; } public int getAver(){//求平均分 int sc = 0; for (Student s:stus){ sc+=s.getAver(); } return sc/stus.size(); } public boolean judge(){//判断班级是否有成绩 for (Student s:stus){ if (!s.getSc().isEmpty()){ return true; } } return false; } public void sort(){//排序 Collections.sort(stus, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return s1.getID().compareTo(s2.getID()); } }); } public ArrayList<Student> getStus() { return stus; } } class Lesson { private String name;//课程名字 private String trait;//课程性质 private String way;//考核方式 public Lesson(String n, String t, String w) { this.name = n; this.trait = t; this.way = w; } public String getName() { return name; } public String getWay() { return way; } }View Code
这是在SourceMonitor生成的图,在Main类中写了所有的对字符串的处理以及输出,主方法里有许多if-else,导致它的复杂度非常高,早在很在前就听老师说过不能全写在主类里,但是就是没改过来,代码的注释也写得比较少,代码还是写的不是很行。
PTA-11
7-4 jmu-Java-04面向对象进阶-03-接口-自定义接口ArrayIntegerStack
这个题目要求定义IntegerStack
接口,用于声明一个存放Integer元素的栈的常见方法,定义IntegerStack的实现类ArrayIntegerStack
,内部使用数组实现。创建时,可指定内部数组大小。这个题目我刚开始选择的是以下代码:
1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner scanner = new Scanner(System.in); 7 int n = scanner.nextInt(); 8 ArrayIntegerStack stack = new ArrayIntegerStack(n); 9 Integer[] nums = new Integer[n]; 10 int m = scanner.nextInt(); 11 for (int i = 0;i<m;i++){ 12 int number = scanner.nextInt(); 13 nums[i] = number; 14 stack.push(number); 15 System.out.println(number); 16 } 17 System.out.println(stack.peek()+","+stack.empty()+","+stack.size()); 18 System.out.println(Arrays.toString(stack.getData())); 19 int out = scanner.nextInt(); 20 for (int i = 0;i<out;i++){ 21 System.out.println(stack.pop()); 22 } 23 System.out.println(stack.peek()+","+stack.empty()+","+stack.size()); 24 System.out.println(Arrays.toString(nums)); 25 } 26 } 27 28 29 30 interface IntegerStack{ 31 public Integer push(Integer item); 32 //如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。 33 34 public Integer pop(); //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null 35 public Integer peek(); //获得栈顶元素,如果为空,则返回null. 36 public boolean empty(); //如果为空返回true 37 public int size(); //返回栈中元素个数 38 } 39 class ArrayIntegerStack implements IntegerStack{ 40 private Integer[] data; 41 private int top = -1; 42 private int capacity = 0; 43 44 public ArrayIntegerStack(int capacity) { 45 this.capacity = capacity; 46 data = new Integer[capacity]; 47 } 48 49 public Integer push(Integer item){ 50 if(item == null || top == capacity - 1){ 51 return null; 52 } 53 data[++top] = item; 54 return item; 55 } 56 57 public Integer pop(){ 58 if(empty()){ 59 return null; 60 } 61 Integer item = data[top]; 62 data[top--] = null; 63 return item; 64 } 65 66 public Integer peek(){ 67 if(empty()){ 68 return null; 69 } 70 return data[top]; 71 } 72 73 public boolean empty(){ 74 return top == -1; 75 } 76 77 public int size(){ 78 return top + 1; 79 } 80 81 // 返回内部数组 82 public Integer[] getData(){ 83 return data; 84 } 85 }View Code
当时是真的没想通为啥要用Top=-1为初始值,通过Top++来实现元素的这种来判断是否到栈顶,非常累赘。后面改了代码就过了了所有的测试点,代码还简洁了许多。
代码如下:
1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 5 public class Main { 6 public static void main(String[] args) { 7 Scanner scanner = new Scanner(System.in); 8 int n = scanner.nextInt(); 9 ArrayIntegerStack stack = new ArrayIntegerStack(n); 10 scanner.nextLine(); 11 int m = scanner.nextInt(); 12 scanner.nextLine(); 13 for (int i = 0; i < m; i++) { 14 int number = scanner.nextInt(); 15 System.out.println(stack.push(number)); 16 } 17 System.out.println(stack.peek() + "," + stack.empty() + "," + stack.size()); 18 System.out.println(Arrays.toString(stack.getData())); 19 int out = scanner.nextInt(); 20 for (int i = 0; i < out; i++) { 21 System.out.println(stack.pop()); 22 } 23 System.out.println(stack.peek() + "," + stack.empty() + "," + stack.size()); 24 System.out.println(Arrays.toString(stack.getData())); 25 } 26 } 27 28 29 interface IntegerStack { 30 public Integer push(Integer item); 31 //如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。 32 33 public Integer pop(); //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null 34 35 public Integer peek(); //获得栈顶元素,如果为空,则返回null. 36 37 public boolean empty(); //如果为空返回true 38 39 public int size(); //返回栈中元素个数 40 } 41 42 class ArrayIntegerStack implements IntegerStack { 43 private Integer[] data; 44 private int size = 0; 45 46 public ArrayIntegerStack(int capacity) { 47 data = new Integer[capacity]; 48 } 49 50 public Integer push(Integer item) { 51 if (item == null || size == data.length) { 52 return null; 53 } 54 data[size++] = item; 55 return item; 56 } 57 58 public Integer pop() { 59 if (empty()) { 60 return null; 61 } 62 size--; 63 return data[size]; 64 } 65 66 public Integer peek() { 67 if (empty()) { 68 return null; 69 } 70 return data[size - 1]; 71 } 72 73 public boolean empty() { 74 return size == 0; 75 } 76 77 public int size() { 78 return size; 79 } 80 81 // 返回内部数组 82 public Integer[] getData() { 83 return data; 84 } 85 }View Code
三.踩坑心得
1.老是忘记double类型的数据有误差,不能直接用相等判断,而是要给出一个误差区间,具体体现在PTA-11课程成绩录入的题目,判断输入的课程分数权重比之和是否等于一,这里应该给出误差区间,如果这个错了,很多测试点都过不了。
2.在做题目时,经常出现判断标准错误的存在,在PTA-7课程成绩录入的时候,自己默认0分就是没有成绩,导致会出现有一个测试点过不了的情况,这是我自己在主观判断上犯的错误,没有选择正确的判断方法去判断是否有成绩,后来选择再Lesson类中加一个判断选报这门课程的学生这门课成绩数组是否为空,才过了所有的测试点。
3.自己多设计一些测试点去测试自己的代码,在写代码时,要尽量考虑普通情况的输入,挑选一些普遍的数据进行测试,我之前自己所做的测试点都是非常简单的数据,导致自己做的测试数据都没啥用,这也算是学到的一些东西吧,在后面的代码测试中,我都是通过自己写的测试点测出了很多问题,才将代码去完善。
四. 代码改进
1.所有的课程成绩录入类题目我都是在主类中完成对输入数据的处理,以及输出结果,这不符合设计原则,应该将这些功能拆散开来,用一些方法分别实现这些功能,让代码能够更加符合结构化设计。
2.在写代码时,代码非常罗嗦,不仅是语法上的问题,还有逻辑上的重复问题,不够简洁,通过一些简写可以使代码更加简洁,也可以将一些步骤做成一些方法,在实现步骤时调用方法,以减少代码的重复。
1 public boolean check1(String Id) {//检查学生ID 2 if (Pattern.matches("\\d{8}",Id)) { 3 return true; 4 } 5 return false; 6 } 7 } 8 可修改为 9 public boolean check1(String Id) {//检查学生ID 10 return Pattern.matches("\\d{8}", Id); 11 } 12 }View Code
五.总结
通过这个阶段的学习,了解到一些比较有用且高效的方法和工具,例如用Map和set进行存储和查找,自己定义比较器的使用,可以根据需求实现不同的排序。还有就是对正则表达式运用更加熟练,能够写出一些匹配合法输入的正则表达式,提高了匹配速度和代码的简练度,对字符串的处理也积累了一些的处理方法。除了题目要求之外,也了解到一些其他有用的方法,例如Arrays.copyOfRange()方法可以将数组中的数据提取出来,String.format不仅可以格式化输出,还可以将一些数据以一定格式化的形式存储。还有就是对类的设计也要比以前更好,也不会再有语法上的问题。但是还是有一些问题的存在,主要就是对面向对象编程的思维还不够了解,编程还是存在一些问题,逻辑重复问题,代码冗杂的问题,不符合面向对象设计的问题,这些都是我在后面的学习过程中要改进的。
六 .评价及建议
Java课程的OBE理念是非常好的,因为它将学生的学习成果放在了教学的核心,帮助我们更好地理解实际问题,增强我们的实践技能。在本学期的学习中我能感觉到老师的教学是有明确目的的,以及课程的评价标准也是非常明确的,一些PTA的设计类题目有明确的考察方向。每次的Blog作业都要求学生在总结时将自己对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见写上,不断收集学生的反馈和意见,从而对课程不断完善和改进。
但是,我觉得本门课程的教学方法需要进一步加强。边讲边练虽然是一种很好的教学策略,但是由于课程难度较高,学生往往需要更多的实践操作和练习,而这方面的教学安排不够完善,有些知识还有完全掌握就开始下一轮了,可以多给一些练习。
此外,PTA题目集驱动的教学过程也存在一些问题,比如一些相关性不大的题目和内容在题目集中混杂,以及题目难度可能跳跃性太大,学生一时难以接受。
教学组织方式方面,线上线下混合式教学的想法不错,但是在实施中需要更多地考虑到学生的学习效果,那些不能在线上完成的实践环节是否可以更好地规划和组织,学习通上的课程去认真看了也能跟上课堂所讲的内容以及也可以扩展知识。
最后,教学模式方面,BOPPPS模式有助于激发学生学习兴趣和主动性,学生可以更好地理解课程内容,为学生提供了非常多的自主学习机会,本学期至少在我看来,大多数学生是非常积极参加上课,课后也有非常多的自学机会,但是需要更加灵活和多变,以适应学生的不同需求和阶段性差异。由于学生个体差异的存在,对于此教学模式,老师可能需要对于某些学生可能需要针对性提供更多帮助和指导,以避免其在学习过程失落和挫败,充分考虑到不同学生的学习需求和差异。
标签:11,总结,return,String,strs,add,PTA7,new,public From: https://www.cnblogs.com/BR-boru/p/17510200.html