PTA7-11总结

发布时间 2023-06-27 23:34:36作者: 小禾火千

 

一.前言

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模式有助于激发学生学习兴趣和主动性,学生可以更好地理解课程内容,为学生提供了非常多的自主学习机会,本学期至少在我看来,大多数学生是非常积极参加上课,课后也有非常多的自学机会,但是需要更加灵活和多变,以适应学生的不同需求和阶段性差异。由于学生个体差异的存在,对于此教学模式,老师可能需要对于某些学生可能需要针对性提供更多帮助和指导,以避免其在学习过程失落和挫败,充分考虑到不同学生的学习需求和差异。