PTA题目集1~3总结

目录:

    1.前言

    2.设计与分析

    3.BUG与修正

    4.缺陷与改进

    5.总结

 

一、前言

  题目集1的题目都是比较基础的题,不需要用到其他的类,而且所有的题代码行数都不超过40行。知识点集中在分支选择和浮点数的处理上,题量适中,难度也较小。比较适合初学Java的学生来熟悉java,了解java与之前所学的c的区别。

  题目集2的题目开始要求学生接触Java的核心——类。部分题的代码行数也超过100行。知识点集中在类的使用、字符的判断上,题量适中,难度有些许上升。

  题目集3的题目中除第二题外都较简单,代码行数都不超过160行。第二题难度较高,程序的逻辑比较复杂,对输入异常的处理也较多,代码行数超过350行。知识点较多,有多种类的配合使用、正则表达式、对输入字符的分析。题量小,难度较大。

 

二、设计与分析

  1.题目集2-7-1 成绩计算-1-类、数组的基本运用  

    创建学生类,包含

    属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)

    方法:计算总分、计算平均分

    输入5个学生的信息,将每个学生的信息封装在一个学生对象中。

    按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

 

    代码如下:
 1 import java.util.Scanner;
 2 import java.text.DecimalFormat;
 3 
 4 class Student{
 5     String ID;
 6     String name;
 7     int s1,s2,s3;
 8     int all;
 9     double average;
10 }
11 
12 public class Main{
13 public static void main(String args[])
14 {
15     Scanner input = new Scanner(System.in);
16     Student stus[]= new Student[5];
17     for(int i=0;i<5;i++)
18     {
19         stus[i] = new Student();
20         
21         stus[i].ID=input.next();
22         stus[i].name=input.next();
23         stus[i].s1=input.nextInt();
24         stus[i].s2=input.nextInt();
25         stus[i].s3=input.nextInt();
26         
27         stus[i].all=stus[i].s1+stus[i].s2+stus[i].s3;
28         stus[i].average=(double)stus[i].all/3;
29         DecimalFormat df = new DecimalFormat("#.00");
30         
31         System.out.println(stus[i].ID+" "+stus[i].name+" "+stus[i].all+" "+df.format(stus[i].average));
32     }
33 }
34 }

    分析:

  此题较为简单,只需要使用一个Student类便可解决,题目也没要求输入异常的判断。值得注意的是题目要求输出的数字格式为精确到小数点后两位,舍去部分按四舍五入规则计入最后一位。因此需要java.text.DecimalFormat来对最后的输出进行处理。

  Student类中按照题目中的提示,拥有属性学号、名字、三项成绩,此外还记录了总成绩、和平均成绩。类中没有计算的方法,计算的过程全在主函数中。

 

  2.题目集2-7-2 成绩计算-2-关联类

    创建成绩类,包含:

    属性:平时成绩(int)、期末成绩(int)

    方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)

    创建学生类,包含:

    属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)

    方法:计算总分、计算平均分

    输入3个学生的信息,将每个学生的信息封装在一个学生对象中。

    按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

    

    代码如下:

 1 import java.util.Scanner;
 2 import java.text.DecimalFormat;
 3 
 4 class Scores{
 5     int usual;
 6     int fin;
 7 
 8     int grades(){
 9         double gra;
10         gra = (double)usual*0.4 + (double)fin*0.6;
11         int res = (int)gra;
12         return res;
13     }
14 }
15 
16 class Student{
17     String ID;
18     String name;
19     Scores c = new Scores();
20     Scores m = new Scores();
21     Scores p = new Scores();
22 
23     int all()
24     {
25         int res;
26         res = c.grades()+m.grades()+p.grades();
27         return res;
28     }
29 
30     double usuaver()
31     {
32         double res;
33         res = (double)(c.usual+m.usual+p.usual)/3;
34         return res;
35     }
36     double finaver()
37     {
38         double res;
39         res = (double)(c.fin+m.fin+p.fin)/3;
40         return res;
41     }
42     double average()
43     {
44         double res;
45         res = (double)all()/3;
46         return res;
47     }
48 }
49 
50 public class Main{
51     public static void main(String args[]){
52         Scanner input = new Scanner(System.in);
53         Student stus[] = new Student[3];
54 
55         for(int i=0;i<3;i++){
56             String s;
57             stus[i] = new Student();
58             for(int j=0;j<3;j++){
59                 stus[i].ID = input.next();
60                 stus[i].name = input.next();
61                 s = input.next();
62                 if(s.compareTo("语文")==0){
63                     stus[i].c.usual = input.nextInt();
64                     stus[i].c.fin = input.nextInt();
65                 }
66                 if(s.compareTo("数学")==0){
67                     stus[i].m.usual = input.nextInt();
68                     stus[i].m.fin = input.nextInt();
69                 }
70                 if(s.compareTo("物理")==0){
71                     stus[i].p.usual = input.nextInt();
72                     stus[i].p.fin = input.nextInt();
73                 }
74             }
75             DecimalFormat df = new DecimalFormat("#.00");
76             System.out.println(stus[i].ID+" "+stus[i].name+" "+stus[i].all()+" "+df.format(stus[i].usuaver())+" "+df.format(stus[i].finaver())+" "+df.format(stus[i].average()));
77         }
78     }
79 }

    分析:

  此题是上一题的升级版,其他条件不变的前提下要求我们至少使用学生类和成绩类,输出也要求输出总成绩、平时成绩、考试成绩、平均成绩。值得注意的是,题目之中只要求输出总成绩和平均成绩,但测试用例和最后的提交都表明了还需要输出平时成绩和考试成绩才是正确答案。

    类图:

  

 

  Scores类负责记录平时成绩和考试成绩,并且有一个计算最终成绩的方法。Student类负责记录一个学生的学号、姓名、成绩信息,并且有计算四种成绩的方法。

 

  3.题目集3-7-2 课程成绩统计程序-1

  某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。

  考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

  考察的总成绩直接等于期末成绩

  必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。

  1、输入:

  包括课程、课程成绩两类信息。

  课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。

  课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

  课程性质输入项:必修、选修

  考核方式输入选项:考试、考察

  课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

  课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

  以上信息的相关约束:

  1)平时成绩和期末成绩的权重默认为0.3、0.7

  2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

  3)学号由8位数字组成

  4)姓名不超过10个字符

  5)课程名称不超过10个字符

  6)不特别输入班级信息,班级号是学号的前6位。

  2、输出:

  输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

  为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

  1)学生课程总成绩平均分按学号由低到高排序输出

  格式:学号+英文空格+姓名+英文空格+总成绩平均分

  如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

  2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出

  格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分

  如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

  3)班级所有课程总成绩平均分按班级由低到高排序输出

  格式:班级号+英文空格+总成绩平均分

  如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

  异常情况:

  1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

  2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

  以上两种情况如果同时出现,按第一种情况输出结果。

  3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

  4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

  5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

  信息约束:

  1)成绩平均分只取整数部分,小数部分丢弃

 

  代码如下:

  1 import java.util.Scanner;
  2 import java.util.Arrays;
  3 import java.util.Comparator;
  4 import java.text.Collator;
  5 import java.util.regex.Pattern;
  6 import java.util.regex.Matcher;
  7 
  8 public class Main{
  9     public static void main(String[] args){
 10         Scanner input = new Scanner(System.in);
 11         Class cla[] = new Class[100];
 12         Course cou[] = new Course[100];
 13         CS cs = new CS();
 14         int classnum=0;
 15         int coursenum=0;
 16         String[] s;
 17         
 18         String s0 = input.nextLine();
 19         
 20         while(!s0.equals("end"))
 21         {
 22             if(!isLegal(s0))
 23             {
 24                 System.out.println("wrong format");
 25                 s0 = input.nextLine();
 26                 continue;
 27             }
 28             
 29             s =s0.split(" ");
 30             if(s.length==3)
 31             {
 32                 boolean isE = false;
 33                 boolean isM = false;
 34                 if(s[1].equals("必修")) isM = true;
 35                 if(s[2].equals("考试")) isE = true;
 36                 
 37                 if(isM&&!isE)
 38                 {
 39                     System.out.println(s[0]+" : course type & access mode mismatch");
 40                     s0 = input.nextLine();
 41                     continue;
 42                 }
 43                 
 44                 boolean isfindC = false;
 45                 for(int i=0;i<coursenum&&!isfindC;i++)
 46                     if(cou[i].name.equals(s[0]))
 47                         isfindC = true;
 48                 
 49                 if(!isfindC)
 50                 {
 51                     cou[coursenum] = new Course(s[0],isM,isE);
 52                     coursenum++;
 53                 }
 54             }
 55             if(s.length>=4)
 56             {
 57                 int Escore=0;
 58                 int Uscore=0;
 59                 int score=0;
 60                 if(s.length == 4)
 61                 {
 62                     
 63                     Escore = Integer.parseInt(s[3]);
 64                     score = Escore;
 65                 }
 66                 if(s.length ==5) 
 67                 {
 68                     Uscore = Integer.parseInt(s[3]);
 69                     Escore = Integer.parseInt(s[4]);
 70                     score = (int)(Escore*0.7+Uscore*0.3);
 71                 }
 72                 
 73                 if(Uscore<0||Uscore>100||Escore<0||Escore>100)
 74                 {
 75                     System.out.println("wrong format");
 76                     s0 = input.nextLine();
 77                     continue;
 78                 }
 79                 
 80                 int i;
 81                 boolean isfindC = false;
 82                 for(i=0;i<coursenum&&!isfindC;i++)
 83                     if(cou[i].name.equals(s[2]))
 84                         isfindC = true;
 85                 i=i-1;
 86                 
 87                 if(!isfindC)
 88                     System.out.println(s[2]+" does not exist");
 89 
 90                 boolean Snum = false;
 91                 if(isfindC)
 92                 {
 93                     if(cou[i].isExam&&s.length == 5||!cou[i].isExam&&s.length == 4)
 94                         Snum = true;
 95                     else System.out.println(s[0]+" "+s[1]+" : access mode mismatch");
 96                 }
 97 
 98                 boolean isFindCS = false;
 99                 isFindCS = cs.isfind(s[1],s[2]);
100                 
101                 if(!isfindC||!Snum||isFindCS);
102                 else if(cou[i].isExam)
103                 {
104                     cou[i].addS(Escore,Uscore);
105                     cs.addCS(s[1],s[2]);
106                 }
107                 else
108                 {
109                     cou[i].addS(Escore);
110                     cs.addCS(s[1],s[2]);
111                 }
112                 
113                 
114                 
115                 boolean isfind = false;
116                 for(i=0;i<classnum&&!isfind;i++)
117                     if(cla[i].ID.equals(s[0].substring(0,6)))
118                         isfind = true;
119                 i=i-1;
120                 
121                 if(!isfind)
122                 {
123                     cla[classnum] = new Class(s[0].substring(0,6));
124                     classnum++;
125                     i=classnum-1;
126                 }
127 
128                 if(!isFindCS)
129                     cla[i].addS(s[0],s[1]);
130                 if(isfindC&&Snum&&!isFindCS)
131                 {
132                     cla[i].addCS(s[0],score);
133                 }
134             }
135             
136             s0 = input.nextLine();
137         }
138         
139         Arrays.sort(cla,0,classnum,new Comparator<Class>() {
140             public int compare(Class a, Class b) {
141                 return a.compareTo(b);
142             }
143          });
144         
145         Arrays.sort(cou,0,coursenum,new Comparator<Course>() {
146             public int compare(Course a, Course b) {
147                 return a.compareTo(b);
148             }
149          });
150         
151         
152         for(int i=0;i<classnum;i++)
153             cla[i].outputAllStu();
154         
155         for(int i=0;i<coursenum;i++)
156             cou[i].outputCourse();
157         
158         for(int i=0;i<classnum;i++)
159             cla[i].outputClass();
160         
161         
162         input.close();
163     }
164 
165     public static boolean isLegal(String s)
166     {
167         String[] s0 =s.split(" ");
168         
169         if(s0.length==3)
170         {
171             if(s.matches("[\\S]{1,10} (必修|选修) (考试|考察)"))
172                 return true;
173             else return false;
174         }
175         if(s0.length==4)
176         {
177             if(s.matches("[0-9]{8} [\\S]{1,10} [\\S]{1,10} [0-9][0-9]?[0-9]?[0-9]?"))
178                 return true;
179             else return false;
180         }
181         if(s0.length==5)
182         {
183             if(s.matches("[0-9]{8} [\\S]{1,10} [\\S]{1,10} [0-9][0-9]?[0-9]?[0-9]? [0-9][0-9]?[0-9]?[0-9]?"))
184                 return true;
185             else return false;
186         }
187 
188         return false;
189     }
190 }
191 
192 class Student{
193     String ID;
194     String name;
195     int allScores;
196     int Cnum;
197 
198     Student(String ID,String name)
199     {
200         this.ID = ID;
201         this.name = name;
202         this.allScores = 0;
203         this.Cnum = 0;
204     }
205 
206     void addC(int scores)
207     {
208         this.allScores += scores;
209         this.Cnum++;
210     }
211 
212     void outputStu()
213     {
214         if(Cnum == 0) System.out.println(ID+" "+name+" did not take any exams");
215         else System.out.println(ID+" "+name+" "+allScores/Cnum);
216     }
217     
218     public int compareTo(Student stu)
219     {
220         return this.ID.compareTo(stu.ID);
221     }
222 }
223 
224 class Class{
225     Student[] stus;
226     String ID;
227     int allScores;
228     int CSnum;
229     int Snum;
230 
231     Class(String ID)
232     {
233         stus = new Student[100];
234         this.ID = ID;
235         allScores = 0;
236         CSnum = 0;
237         Snum = 0;
238     }
239 
240     void addCS(String SID,int scores)
241     {
242         boolean isfind = false;
243         int i;
244         for(i=0;i<Snum&&!isfind;i++)
245             if(stus[i].ID.equals(SID)) isfind = true;
246         i--;
247         
248         stus[i].addC(scores);
249         allScores += scores;
250         CSnum++;
251     }
252     
253     void addS(String SID,String name)
254     {
255         boolean isfind = false;
256         int i;
257         for(i=0;i<Snum&&!isfind;i++)
258             if(stus[i].ID.equals(SID)) isfind = true;
259         
260         if(!isfind)
261         {
262             stus[Snum] = new Student(SID,name);
263             Snum++;
264         }
265     }
266 
267     void outputClass()
268     {
269         if(CSnum == 0) System.out.println(ID+" has no grades yet");
270         else System.out.println(ID+" "+allScores/CSnum);
271     }
272     
273     void outputAllStu()
274     {
275         Arrays.sort(stus,0,Snum,new Comparator<Student>() {
276            public int compare(Student a, Student b) {
277                return a.compareTo(b);
278            }
279         });
280         
281         for(int i=0;i<Snum;i++)
282                 stus[i].outputStu();
283     }
284     
285     public int compareTo(Class cla)
286     {
287         return this.ID.compareTo(cla.ID);
288     }
289 }
290 
291 class Course{
292     String name;
293     boolean isMust;
294     boolean isExam;
295     int allES;
296     int allUS;
297     int allFS;
298     int Snum;
299     
300     Course(String name, boolean isMust, boolean isExam)
301     {
302         this.name = name;
303         this.isMust = isMust;
304         this.isExam = isExam;
305         allES = 0;
306         allUS = 0;
307         Snum = 0;
308     }
309     
310     void addS(int ES)
311     {
312         allES += ES;
313         allFS += ES;
314         Snum++;
315     }
316     
317     void addS(int ES,int US)
318     {
319         allES += ES;
320         allUS += US;
321         allFS += (int)(ES*0.7+US*0.3);
322         Snum++;
323     }
324     
325     void outputCourse()
326     {
327         if(Snum==0) System.out.println(name+" has no grades yet");
328         else if(isExam) System.out.println(name+" "+allUS/Snum+" "+allES/Snum+" "+allFS/Snum);
329         else System.out.println(name+" "+allES/Snum+" "+allFS/Snum);
330     }
331     
332     public int compareTo(Course cou)
333     {
334         //return this.name.compareTo(cou.name);
335         Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
336         return compare.compare(this.name, cou.name);
337     }
338 }
339 
340 class CS{
341     String[] cou;
342     String[] stu;
343     int CSnum;
344 
345     CS()
346     {
347         CSnum = 0;
348         cou = new String[100];
349         stu = new String[100];
350     }
351     
352     boolean isfind(String s,String c)
353     {
354         for(int i=0;i<CSnum;i++)
355         {
356             if(stu[i].equals(s)&&cou[i].equals(c))
357                 return true;
358         }
359         return false;
360     }
361 
362     void addCS(String s,String c)
363     {
364         stu[CSnum] = s;
365         cou[CSnum] = c;
366         CSnum++;
367     }
368 }

    分析:此题又是上一题的升级版,所需要的类更多,需要对输入的格式进行复杂的判断,需要的逻辑判断也更为复杂。我在处理这道题时,先忽略了输入异常的判断,在能够完成相应的功能后再对测试用例进行一个一个的处理,不断的增加对输入异常判断,直到通过所有的测试用例。

    类图:

  

    程序读入的是一整行的字符,在程序每次读入字符后会判断该字符是否是“end”若是便会结束读入,随后开始按照相应的格式输出数据;若不是便会对输入的字符进行分析。

    首先要分析的就是输入的字符究竟是课程信息还是学生的选课信息。我们注意到,所有的课程信息都被空格符号分为了三段,而学生选课信息都是四段或者五段。依照整个特性,我们可以利用split()方法来对输入的字符进行切割,随后只要该字符能被切为几段来判断该字符是什么信息,并通过相应的正则表达式来判断输入的字符是否合法。

    倘若输入的是课程信息,就先判断原先是否记录过相同的信息并且输入的数据是否合法,再创建新的课程对象,设置相应的参数。

    倘若输入的是学生信息,也先判断原先是否记录过相同的信息并且输入的数据是否合法,再创建新的学生对象,设置相应的参数。

    值得注意的是输入不合法的处理是直接忽略此信息;而输入与此前输入矛盾时不能直接忽略信息,应该继续创建对象,不过信息不能记录下来,需要让信息为空。

    在结束输出后,程序会依次按照格式输出数据。值得注意的是,题目明确的要求了输出要有顺序的输出,于是对这些对象的数组的排序就必不可少。我在查阅了相关资料后采用了对比较函数compareTo重构和使用Arrays类的方法进行排序,随后再按次序输出。

 

   4.题目集2-7-7 菜单计价程序-1

  某饭店提供4种菜,每种菜品的基础价格如下:
  西红柿炒蛋 15
  清炒土豆丝 12
  麻婆豆腐 12
  油淋生菜 9

  设计点菜计价程序,根据输入的订单,计算并输出总价格。
  订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
  每条点菜记录包含:菜名、份额两个信息。
  份额可选项包括:1、2、3,分别代表小、中、大份)

  不同份额菜价的计算方法:
  小份菜的价格=菜品的基础价格。
  中份菜的价格=菜品的基础价格1.5。
  小份菜的价格=菜品的基础价格
2。

  如果计算出现小数,按四舍五入的规则进行处理。

 

  代码如下:

import java.util.Scanner;
import java.math.BigDecimal;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Order order = new Order();
        order.records = new Record[100];
        
        int i=0;
        String name;
        int p;
        name = input.next();
        while(!name.equals("end"))
        {
            p = input.nextInt();
            Dish d = menu.searthDish(name);
            if(d.unit_price==0) System.out.println(name+" does not exist");
            else{
                order.records[i] = new Record();
                order.records[i].d = d;
                order.records[i].portion = p;
                i++;
            }
            name = input.next();
        }
        
        int res = order.getTotalPrice(i);
        
        System.out.println(res);
    }
}

class Dish{
    String name;
    int unit_price;

     public int getPrice(int portion){
        int res=0;
        BigDecimal bg = new BigDecimal((double)this.unit_price*1.5);
        if(portion==1) res = this.unit_price;
        if(portion==2) res = (int)bg.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
        if(portion==3) res = this.unit_price*2;
        return res;
    }
}

class Menu{
    Dish[] dishs;

    public Dish searthDish(String dishName){
        Dish dish= new Dish();
        dish.unit_price=0;
        for(int i=0;i<4;i++)
        {
            if(this.dishs[i].name.equals(dishName))
                return this.dishs[i];
        }
        return dish;
    }

    public Menu(){
        this.dishs = new Dish[4];

        this.dishs[0] = new Dish();
        this.dishs[0].name = "西红柿炒蛋";
        this.dishs[0].unit_price = 15;

        this.dishs[1] = new Dish();
        this.dishs[1].name = "清炒土豆丝";
        this.dishs[1].unit_price = 12;

        this.dishs[2] = new Dish();
        this.dishs[2].name = "麻婆豆腐";
        this.dishs[2].unit_price = 12;

        this.dishs[3] = new Dish();
        this.dishs[3].name = "油淋生菜";
        this.dishs[3].unit_price = 9;
    }
}

class Record{
    Dish d;
    int portion;

    public int getPrice(){
        return this.d.getPrice(this.portion);
    }
}

class Order{
    Record[] records;

    public int getTotalPrice(int x){
        
        int res=0;
        for(int i=0;i<x;i++){
            res += records[i].getPrice();
        }
        return res;
        
    }
}

  分析:使用的类有Dish,Menu,Record,Order。其中Dish和Menu是群聚关系,Record和Order也是群聚关系。

 

三、踩坑与修正

  1.我相信有很多原先学过C语言,再来学习Java的同志都踩过这个坑——类数组的建立。

    先来看代码和报错:

    

 1 import java.util.Scanner;
 2 import java.text.DecimalFormat;
 3 
 4 class Student{
 5     String ID;
 6     String name;
 7     int s1,s2,s3;
 8     int all;
 9     double average;
10 }
11 
12 public class Main{
13 public static void main(String args[])
14 {
15     Scanner input = new Scanner(System.in);
16     Student stus[]= new Student[5];
17     for(int i=0;i<5;i++)
18     {
19         stus[i].ID=input.next();
20         stus[i].name=input.next();
21         stus[i].s1=input.nextInt();
22         stus[i].s2=input.nextInt();
23         stus[i].s3=input.nextInt();
24         
25         stus[i].all=stus[i].s1+stus[i].s2+stus[i].s3;
26         stus[i].average=(double)stus[i].all/3;
27         DecimalFormat df = new DecimalFormat("#.00");
28         
29         System.out.println(stus[i].ID+" "+stus[i].name+" "+stus[i].all+" "+df.format(stus[i].average));
30     }
31 }
32 }

    这样的代码在习惯了C语言的人看来似乎没有任何问题,但一旦运行就会报错:

Cannot assign field "ID" because "stus[i]" is null

    意思是stus[i]不存在,那么对于习惯了C语言的人来说就很奇怪了,不是在前面new了一个数组对象了吗。原来在new了一个数组对象后,这个对中依然是什么都没有,我们还需要对数组中的每一个元素都new一遍它才会存在对象。而此前new了数组对象只是申请了一个对应的空间而已。

 

四、缺陷与改进

  1.显而易见的是,我写的代码的圈复杂度过高。主函数都特别的复杂,几乎所有的逻辑判断、分支选择、循环都写在一个主函数中。只要题目复杂,圈复杂度就会很高。这也导致维护我写的代码十分困难。即使是十分浅显的BUG也很难发现,更别说那些复杂的逻辑错误。

   改进的方法就是拆解主函数,将一个逻辑复杂的主函数拆解为一个个逻辑简单的小函数,例如在题目集3-7-2 课程成绩统计程序-1一题中,我就将对输入字符是否合法的判断写在另外的方法之中,使得主函数的圈复杂度降低。

 

五、总结

  题目集1~3是我接触Java做的第一次作业,可以说是我Java的开始。在开始阶段我主要学到了Java的语法、对类的简单使用和正则表达式。

  在对题目集1~3的总结过程中,回首过去写的代码,各种格式不规范映入眼帘,各种为了过题而走的捷径不断敲打着我。也许到了能够正视各种题目,迎难而上的时候我的Java能力才会真正的提升吧。此外我发现我写的大部分代码依然带着C语言的气质,常常也会因为这个而出现BUG,转变这个思想也是我现在这个阶段重要的课题。

  这是我第一次在博客园中发表博客,还有许多的内容不够完善,但我依然为我踏出第一步而感到自豪。我相信在多次博客的发表中,我也能锻炼自己的能力。

  希望能与大家一起提升Java的能力,谢谢各位的耐心观看!

热门相关:嫁偶天成   嫡嫁千金   紫府仙缘   交换享用妻子   重生成偏执霍少的小仙女