PTA题目集7~8+期末总结

发布时间 2023-12-07 18:09:54作者: 我就是个鹌鹑

目录:

    1.前言

    2.设计与分析

    3.BUG与修正

    4.缺陷与改进

    5.总结

一、前言

  题目集7的成绩统计2有57个人获得了满分,相较于成绩统计1的31人满分有很大的进步。我认为主要的原因是在成绩统计1发布时间较早,很多同学都是在最后才来写PTA的作业,没有时间的规划,才导致成绩统计1通过率低。而后来同学意识到PTA难度逐步提升,才开始重视PTA的作业,所以难度较大的成绩统计2反而通过率较高。

  题目集8的成绩统计3有48个人获得满分,在难度进一步提升之后,通过率就正常的下降了。我认为成绩统计3的主要难点就是最终的成绩计算方式发生了改变,导致需要修改源码,难度较为适中。

  在期末考试中十分有意思的是,我在看似最简单的第一道编程题上花的时间反而是最多的。在后续更难的迭代题中,意外的十分顺利。我认为主要的原因就是题目要求的类结构十分的适合这两次迭代,后面的题只要用前题的代码稍稍修改,就可以实现更加复杂的功能。我认为这就是面对对象编程的最大的优势!

 

二、设计与分析

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

课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。

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

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

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

实验的总成绩等于课程每次实验成绩的平均分

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

1、输入:

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

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

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

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

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

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

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

实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩

实验次数至少4次,不超过9次

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

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

    分析:

  此题的重点是在对实验成绩的数量判断和计算上。

    类图:

    本题的主要难点就是对实验成绩的数量判断上,有时数量错误是直接算作格式错误,有时数量错误是算作成绩不匹配,这里的逻辑较为复杂。

    本题还有一处难点就是在实验成绩的计算上,由于实验成绩的计算和考试成绩、考察成绩的计算完全不一样,所以需要重新写代码,还需要注意不同方法的使用,难度适中。我是在成绩类中就定义好了多种计算方法,然后在成绩类中加入计算方法的属性。计算时根据计算方法来决定使用什么方法。

 

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

课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,

要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。

题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。

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

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

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

实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)

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

1、输入:

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

课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。

考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重

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

实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重

实验次数至少4次,不超过9次

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

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

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

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

实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

以上信息的相关约束:

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

2)学号由8位数字组成

3)姓名不超过10个字符

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

5)不特别输入班级信息,班级号是学号的前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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"

7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"

信息约束:

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             int datasort = dataSort(s0);        //1:课程   2:成绩
 23             
 24             if(datasort == 0)
 25             {
 26                 System.out.println("wrong format");
 27                 s0 = input.nextLine();
 28                 continue;
 29             }
 30             
 31             s =s0.split(" ");
 32             if(datasort == 1)
 33             {
 34                 boolean isfindC = false;
 35                 for(int i=0;i<coursenum&&!isfindC;i++)
 36                     if(cou[i].name.equals(s[0]))
 37                         isfindC = true;
 38                 
 39                 if(isfindC)
 40                 {
 41                     s0 = input.nextLine();
 42                     continue;
 43                 }
 44                 
 45                 int exam = 0;
 46                 int type = 0;
 47                 if(s[1].equals("必修")) type = 1;
 48                 if(s[1].equals("选修")) type = 2;
 49                 if(s[1].equals("实验")) type = 3;
 50                 
 51                 if(s[2].equals("考试")) exam = 1;
 52                 if(s[2].equals("考察")) exam = 2;
 53                 if(s[2].equals("实验")) exam = 3;
 54                 
 55                 if(type==1&&exam!=1||type==3&&exam!=3||type==2&&exam==3)
 56                 {
 57                     System.out.println(s[0]+" : course type & access mode mismatch");
 58                     s0 = input.nextLine();
 59                     continue;
 60                 }
 61                 
 62                 if(exam==3&&Integer.parseInt(s[3])+4 !=s.length)
 63                 {
 64                     System.out.println(s[0]+" : number of scores does not match");
 65                     s0 = input.nextLine();
 66                     continue;
 67                 }
 68                 
 69                 if(exam==1)
 70                 {
 71                     double allSW = 0;
 72                     allSW = Double.parseDouble(s[3])+Double.parseDouble(s[4]);
 73                     if(allSW-1>0.00001||allSW-1<-0.00001)
 74                     {
 75                         System.out.println(s[0]+" : weight value error");
 76                         s0 = input.nextLine();
 77                         continue;
 78                     }
 79                 }
 80                 
 81                 if(exam==3)
 82                 {
 83                     double allSW = 0;
 84 
 85                     for(int i=4;i<s.length;i++)
 86                         allSW += Double.parseDouble(s[i]);
 87                     
 88                     if(allSW-1>0.00001||allSW-1<-0.00001)
 89                     {
 90                         System.out.println(s[0]+" : weight value error");
 91                         s0 = input.nextLine();
 92                         continue;
 93                     }
 94                 }
 95                 
 96                 
 97                 
 98                 if(!isfindC)
 99                 {
100                     if(exam==1)
101                         cou[coursenum] = new Course(s[0],type,exam,2);
102                     if(exam==2)
103                         cou[coursenum] = new Course(s[0],type,exam,1);
104                     if(exam==3)
105                         cou[coursenum] = new Course(s[0],type,exam,Integer.parseInt(s[3]));
106                     
107                     if(exam==1)
108                         for(int i=3;i<s.length;i++)
109                             cou[coursenum].addSW(Double.parseDouble(s[i]));
110                     
111                     if(exam==2) cou[coursenum].addSW(1);
112                     
113                     if(exam==3)
114                         for(int i=4;i<s.length;i++)
115                             cou[coursenum].addSW(Double.parseDouble(s[i]));
116                     
117                     coursenum++;
118                 }
119             }
120             if(datasort == 2)
121             {
122                 int Fscore=0;
123                 int[] score = new int[10];
124                 int stuScoreNum = 0;
125                 boolean experimentNum = false;
126                 if(s.length == 4)
127                 {
128                     score[stuScoreNum++] = Integer.parseInt(s[3]);
129                 }
130                 if(s.length ==5) 
131                 {
132                     score[stuScoreNum++] = Integer.parseInt(s[3]);
133                     score[stuScoreNum++] = Integer.parseInt(s[4]);
134                 }
135                 if(s.length > 5) 
136                 {
137                     boolean scoreFormat = true;
138                     int scoreNum = s.length-3;
139                     
140                     for(int i=3;i<s.length;i++)
141                     {
142                         if(Integer.parseInt(s[i])>100)
143                             scoreFormat = false;
144                         score[stuScoreNum++] = Integer.parseInt(s[i]);
145                     }
146                     if(!scoreFormat)
147                     {
148                         System.out.println("wrong format");
149                         s0 = input.nextLine();
150                         continue;
151                     }
152                     
153                 }
154                 
155                 
156                 for(int i=0;i<stuScoreNum;i++)
157                     if(score[i]<0||score[i]>100)
158                     {
159                         System.out.println("wrong format");
160                         s0 = input.nextLine();
161                         continue;
162                     }
163                 
164                 
165                 int i;
166                 boolean isfindC = false;
167                 for(i=0;i<coursenum&&!isfindC;i++)
168                     if(cou[i].name.equals(s[2]))
169                         isfindC = true;
170                 i=i-1;
171                 if(!isfindC)    //未在课表上找到该课
172                     System.out.println(s[2]+" does not exist");
173 
174                 
175                 boolean Snum = false;
176                 if(isfindC)
177                 {
178                     if(cou[i].SWnum==stuScoreNum)
179                         Snum = true;
180                     else
181                         System.out.println(s[0]+" "+s[1]+" : access mode mismatch");
182                 }
183                 
184                 if(Snum)
185                 {
186                     double allscore = 0.00001;
187                     for(int j=0;j<stuScoreNum;j++)
188                     {
189                         allscore += score[j]*cou[i].SW[j];
190                     }
191                     //System.out.println(s[1]+allscore);
192                     Fscore = (int)allscore;
193                 }
194                 
195                 boolean isFindCS = false;
196                 isFindCS = cs.isfind(s[0],s[2]);
197                 
198                 if(!isfindC||!Snum||isFindCS);
199                 else
200                 {
201                     cou[i].addS(Fscore);
202                     cs.addCS(s[0],s[2]);
203                 }
204 
205                 
206                 boolean isfind = false;
207                 for(i=0;i<classnum&&!isfind;i++)
208                     if(cla[i].ID.equals(s[0].substring(0,6)))
209                         isfind = true;
210                 i=i-1;
211                 
212                 if(!isfind)
213                 {
214                     cla[classnum] = new Class(s[0].substring(0,6));
215                     classnum++;
216                     i=classnum-1;
217                 }
218 
219                 if(!isFindCS)
220                     cla[i].addS(s[0],s[1]);
221                 if(isfindC&&Snum&&!isFindCS)
222                 {
223                     cla[i].addCS(s[0],Fscore);
224                 }
225             }
226             
227             s0 = input.nextLine();
228         }
229         
230         Arrays.sort(cla,0,classnum,new Comparator<Class>() {
231             public int compare(Class a, Class b) {
232                 return a.compareTo(b);
233             }
234          });
235         
236         Arrays.sort(cou,0,coursenum,new Comparator<Course>() {
237             public int compare(Course a, Course b) {
238                 return a.compareTo(b);
239             }
240          });
241         
242         
243         for(int i=0;i<classnum;i++)
244             cla[i].outputAllStu();
245         
246         for(int i=0;i<coursenum;i++)
247             cou[i].outputCourse();
248         
249         for(int i=0;i<classnum;i++)
250             cla[i].outputClass();
251         
252         
253         input.close();
254     }
255     
256     
257     public static int dataSort(String s)        //1:课程   2:成绩
258     {
259         int datasort = 0;
260         
261         if(s.matches("[a-zA-Z\\u4e00-\\u9fa5]+ (选修|必修|实验) (考试|考察|实验)( [4-9])?( [0-9]+.[0-9]+){0,10}"))
262             datasort = 1;//课程信息
263         if(s.matches("[0-9]{8} [\\u4e00-\\u9fa5]+ [a-zA-Z\\u4e00-\\u9fa5]+ (0|[1-9][0-9]?[0-9]?)"))
264             datasort = 2;//考察成绩
265         if(s.matches("[0-9]{8} [\\u4e00-\\u9fa5]+ [a-zA-Z\\u4e00-\\u9fa5]+ (0|[1-9][0-9]?[0-9]?) (0|[1-9][0-9]?[0-9]?)"))
266             datasort = 2;//考试成绩
267         if(s.matches("[0-9]{8} [\\u4e00-\\u9fa5]+ [a-zA-Z\\u4e00-\\u9fa5]+( 0| [1-9][0-9]?[0-9]?){2,9}"))
268             datasort = 2;//实验成绩
269         
270         return datasort;
271     }
272 }
273 
274 class Student{
275     String ID;
276     String name;
277     int allScores;
278     int Cnum;
279 
280     Student(String ID,String name)
281     {
282         this.ID = ID;
283         this.name = name;
284         this.allScores = 0;
285         this.Cnum = 0;
286     }
287 
288     void addC(int scores)
289     {
290         this.allScores += scores;
291         this.Cnum++;
292     }
293 
294     void outputStu()
295     {
296         if(Cnum == 0) System.out.println(ID+" "+name+" did not take any exams");
297         else System.out.println(ID+" "+name+" "+allScores/Cnum);
298     }
299     
300     public int compareTo(Student stu)
301     {
302         return this.ID.compareTo(stu.ID);
303     }
304 }
305 
306 class Class{
307     Student[] stus;
308     String ID;
309     int allScores;
310     int CSnum;
311     int Snum;
312 
313     Class(String ID)
314     {
315         stus = new Student[100];
316         this.ID = ID;
317         allScores = 0;
318         CSnum = 0;
319         Snum = 0;
320     }
321 
322     void addCS(String SID,int scores)
323     {
324         boolean isfind = false;
325         int i;
326         for(i=0;i<Snum&&!isfind;i++)
327             if(stus[i].ID.equals(SID)) isfind = true;
328         i--;
329         
330         stus[i].addC(scores);
331         allScores += scores;
332         CSnum++;
333     }
334     
335     void addS(String SID,String name)
336     {
337         boolean isfind = false;
338         int i;
339         for(i=0;i<Snum&&!isfind;i++)
340             if(stus[i].ID.equals(SID)) isfind = true;
341         
342         if(!isfind)
343         {
344             stus[Snum] = new Student(SID,name);
345             Snum++;
346         }
347     }
348 
349     void outputClass()
350     {
351         if(CSnum == 0) System.out.println(ID+" has no grades yet");
352         else System.out.println(ID+" "+allScores/CSnum);
353     }
354     
355     void outputAllStu()
356     {
357         Arrays.sort(stus,0,Snum,new Comparator<Student>() {
358            public int compare(Student a, Student b) {
359                return a.compareTo(b);
360            }
361         });
362         
363         for(int i=0;i<Snum;i++)
364                 stus[i].outputStu();
365     }
366     
367     public int compareTo(Class cla)
368     {
369         return this.ID.compareTo(cla.ID);
370     }
371 }
372 
373 class Course{
374     String name;
375     int type;//1:必修  2:选修  3:实验
376     int exam;//1:考试  2:考察  3:实验
377     int allFS;
378     int Snum;
379     int SWnum;
380     int SWnumi;
381     double[] SW;
382     
383     Course(String name, int type, int exam,int SWnum)
384     {
385         this.name = name;
386         this.type = type;
387         this.exam = exam;
388         Snum = 0;
389 
390         this.SWnum = SWnum;
391         this.SWnumi = 0;
392         SW = new double[100];
393     }
394     
395     void addSW(double sw)
396     {
397         SW[SWnumi++] = sw;
398     }
399     
400     void addS(int FS)
401     {
402         allFS += FS;
403         Snum++;
404     }
405     
406     void outputCourse()
407     {
408         if(Snum==0) System.out.println(name+" has no grades yet");
409         else System.out.println(name+" "+allFS/Snum);
410     }
411     
412     public int compareTo(Course cou)
413     {
414         //return this.name.compareTo(cou.name);
415         Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
416         return compare.compare(this.name, cou.name);
417     }
418 }
419 
420 class CS{
421     String[] cou;
422     String[] stu;
423     int CSnum;
424 
425     CS()
426     {
427         CSnum = 0;
428         cou = new String[100];
429         stu = new String[100];
430     }
431     
432     boolean isfind(String s,String c)
433     {
434         for(int i=0;i<CSnum;i++)
435         {
436             if(stu[i].equals(s)&&cou[i].equals(c))
437                 return true;
438         }
439         return false;
440     }
441 
442     void addCS(String s,String c)
443     {
444         stu[CSnum] = s;
445         cou[CSnum] = c;
446         CSnum++;
447     }
448 }

    分析:

  本题相较于成绩统计2修改了成绩计算的方法,加入了权重这一特点。

    类图:

 

  本题的主要难点就是对成绩的计算方法进行了重新定义,还改变了输入的方式,需要大规模修改代码,难度加大。

  我在课程类中加入了一个double类型的数组,用于存储权重。在计算时,就将权重取出计算乘法运算,计算的结果以double的形式存储在学生类中。最后计算时将所有学生的成绩转换为int类型再进行求平均的运算。

  这题有一个小坑,就是为了防止四舍五入的错误,需要将结果进行double和int的转换。而又恰好有一题由于计算机的精度问题,将87计算成了86.99999。再经过转换成了86,导致结果错误。为了避开这一坑,我将最终成绩初始化为0.00001,这样即避免了这一个坑,也不会影响其他结果。

 

  3.题目7-1 立体图形问题

编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。

类结构如下图所示(参考):

image.png
试编程完成如上类设计,主方法源码如下(可直接拷贝使用):

 
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    double side = input.nextDouble();
        
    display(new Cube(side));
    display(new RegularPyramid(side));
}

其中,display(Solid solid)方法为定义在Main类中的静态方法,作用为体现程序的多态性。

注:正三棱锥的体积计算公式为底面积*高/3。

输入格式:

输入一个实型数,分别作为正方体的边长和正三棱锥的边长。

输出格式:

分别输出正方体的表面积、体积以及正棱锥的表面积和体积。保留两位小数,建议使用String.format(“%.2f”,value)

进行小数位数控制。

 

  代码如下:

 1 import java.util.Scanner;
 2 import java.math.BigDecimal;
 3 
 4 public class Main
 5 {
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8         Scanner input = new Scanner(System.in);
 9         double side = input.nextDouble();
10             
11         display(new Cube(side));
12         display(new RegularPyramid(side));
13     }
14     
15     public static void display(Solid solid)
16     {
17         double value1 = solid.getArea();
18         double value2 = solid.getVolume();
19         System.out.println(String.format("%.2f",value1));
20         System.out.println(String.format("%.2f",value2));
21         
22     }
23     
24 }
25 
26 abstract class Solid
27 {
28     double side = 0;
29     
30     public Solid(double side)
31     {
32         this.side = side;
33     }
34     
35     abstract double getArea();
36     
37     abstract double getVolume();
38 }
39 
40 class Cube extends Solid
41 {
42     public Cube(double side) {
43         super(side);
44     }
45 
46     double getArea()
47     {
48         return this.side*this.side*6;
49     }
50     
51     double getVolume()
52     {
53         return this.side*this.side*this.side;
54     }
55 }
56 
57 class RegularPyramid extends Solid
58 {
59 
60     public RegularPyramid(double side) {
61         super(side);
62         // TODO Auto-generated constructor stub
63     }
64     
65     double getArea()
66     {
67         return this.side*this.side*Math.sqrt(3);
68     }
69     
70     double getVolume()
71     {
72         return this.side*this.side*this.side*Math.sqrt(2)/12;
73     }
74 }

    分析:

  本题考察的继承和多态,是面对对象编程的一大重点,可以很好的体现代码的可扩展性。

  我先写了一个抽象的Solid类,然后写了正方体类和正三棱锥类继承自Solid类,在Main中使用的多态,一个对象即是Solid又是正方体。这样就可以简化Main中的代码,又可以又很大的可扩展性。

 

  4.题目7-1 立体图形问题

问题描述:本问题中的魔方有两种,一种是正方体魔方,一种是正三棱锥魔方,其中,正方体或正三棱锥魔方是由单元正方体或正三棱锥组成,单元正方体或正三棱锥的个数由阶数(即层数)决定,即魔方边长=阶数*单元边长。魔方如下图所示:

image.png

 

利用“立体图形”问题源码,实现如下功能:

魔方有三个属性:颜色,阶数,类型(正方体魔方、正三棱锥魔方),程序要求输出魔方的颜色、表面积和体积。参考设计类图如下所示:

image.png

主方法部分可参考如下源码(可拷贝直接使用):


 
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();        
        
        RubikCube cube1 = new SquareCube(color, layer,new Cube(side)); 
                
        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        
        RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }
}

其中,display(RubikCube cube)方法为Main类中定义的静态方法,用户输出魔方的信息,用于体现多态性。

输入格式:

第一部分:正方体魔方颜色、阶数、单元正方体边长,以空格或回车分隔;

第二部分:正三棱锥魔方颜色、阶数、单元正三棱锥边长,以空格或回车分隔。

输出格式:

正方体魔方颜色

正方体魔方表面积

正方体魔方体积

正三棱锥魔方颜色

正三棱锥魔方表面积
正三棱锥魔方体积

注:小数点保留两位

 

  代码如下:

  1 import java.util.Scanner;
  2 import java.math.BigDecimal;
  3 
  4 public class Main {
  5 
  6     public static void main(String[] args) {
  7         // TODO Auto-generated method stub
  8         Scanner input = new Scanner(System.in);
  9         
 10         String color = input.next();
 11         int layer = input.nextInt();
 12         double side = input.nextDouble();        
 13         
 14         RubikCube cube1 = new SquareCube(color, layer,new Cube(side*layer)); 
 15                 
 16         color = input.next();
 17         layer = input.nextInt();
 18         side = input.nextDouble();
 19         
 20         RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side*layer));
 21         display(cube1);
 22         display(cube2);
 23     }
 24     
 25     public static void display(RubikCube cube)
 26     {
 27         String color = cube.getcolor();
 28         double value1 = cube.solid.getArea();
 29         double value2 = cube.solid.getVolume();
 30         System.out.println(color);
 31         System.out.println(String.format("%.2f",value1));
 32         System.out.println(String.format("%.2f",value2));
 33         
 34     }
 35 }
 36 
 37 abstract class Solid
 38 {
 39     double side = 0;
 40     
 41     public Solid(double side)
 42     {
 43         this.side = side;
 44     }
 45     
 46     abstract double getArea();
 47     
 48     abstract double getVolume();
 49 }
 50 
 51 class Cube extends Solid
 52 {
 53     public Cube(double side) {
 54         super(side);
 55     }
 56 
 57     double getArea()
 58     {
 59         return this.side*this.side*6;
 60     }
 61     
 62     double getVolume()
 63     {
 64         return this.side*this.side*this.side;
 65     }
 66 }
 67 
 68 class RegularPyramid extends Solid
 69 {
 70 
 71     public RegularPyramid(double side) {
 72         super(side);
 73         // TODO Auto-generated constructor stub
 74     }
 75     
 76     double getArea()
 77     {
 78         return this.side*this.side*Math.sqrt(3);
 79     }
 80     
 81     double getVolume()
 82     {
 83         return this.side*this.side*this.side*Math.sqrt(2)/12;
 84     }
 85 }
 86 
 87 abstract class RubikCube
 88 {
 89     String color;
 90     int layer;
 91     Solid solid;
 92     
 93     public RubikCube(String color,int layer,Solid solid)
 94     {
 95         this.color = color;
 96         this.layer = layer;
 97         this.solid = solid;
 98     }
 99     
100     String getcolor()
101     {
102         return color;
103     }
104 }
105 
106 class SquareCube extends RubikCube
107 {
108 
109     public SquareCube(String color, int layer, Solid solid) {
110         super(color, layer, solid);
111         // TODO Auto-generated constructor stub
112     }
113 }
114 
115 class RegularPyramidCube extends RubikCube
116 {
117 
118     public RegularPyramidCube(String color, int layer, Solid solid) {
119         super(color, layer, solid);
120         // TODO Auto-generated constructor stub
121     }
122 }

    分析:

  本题是上一题的迭代,增加了魔方的相关类,输入输出都改变了。但是由于上一题的代码具有很好的可扩展性,所有这一题写起来也并没有十分复杂。在上一题代码不变的前提下,增加了魔方的类,然后继承自Solid类,这样魔方就能有立体图形的各种属性和方法。然后再增加魔方特有的方法就可以了。

 

  5.题目7-3 魔方排序问题

在魔方问题的基础上,重构类设计,实现列表内魔方的排序功能(按照魔方的体积进行排序)。

提示:题目中RubikCube类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

 
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color;
        int layer;
        double side;
        RubikCube cube;
        
        ArrayList<RubikCube> list = new ArrayList<>();
        
        int choice = input.nextInt();
        
        while(choice != 0) {
            switch(choice) {
            case 1://SquareCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new SquareCube(color, layer,new Cube(side)); 
                list.add(cube);
                break;
            case 2://RegularPyramidCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); 
                list.add(cube);
                break;
            }
            choice = input.nextInt();
        }
        
        list.sort(Comparator.naturalOrder());//正向排序
        
        for(int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i).getColor() + " " + 
        String.format("%.2f", list.get(i).getArea()) + " " + 
        String.format("%.2f", list.get(i).getVolume()) );
            System.out.println("");
        }            
    }    
}

输入格式:

输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)

魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长

..循环..

输出格式:

按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。

 

  代码如下:

  1 import java.util.ArrayList;
  2 import java.util.Comparator;
  3 import java.util.Scanner;
  4 import java.math.BigDecimal;
  5 
  6 public class Main {
  7 
  8     public static void main(String[] args) {
  9         // TODO Auto-generated method stub
 10         Scanner input = new Scanner(System.in);
 11         
 12         String color;
 13         int layer;
 14         double side;
 15         RubikCube cube;
 16         
 17         ArrayList<RubikCube> list = new ArrayList<>();
 18         
 19         int choice = input.nextInt();
 20         
 21         while(choice != 0) {
 22             switch(choice) {
 23             case 1://SquareCube
 24                 color = input.next();
 25                 layer = input.nextInt();
 26                 side = input.nextDouble();
 27                 cube = new SquareCube(color, layer,new Cube(side*layer)); 
 28                 list.add(cube);
 29                 break;
 30             case 2://RegularPyramidCube
 31                 color = input.next();
 32                 layer = input.nextInt();
 33                 side = input.nextDouble();
 34                 cube = new RegularPyramidCube(color, layer,new RegularPyramid(side*layer)); 
 35                 list.add(cube);
 36                 break;
 37             }
 38             choice = input.nextInt();
 39         }
 40         
 41         //list.sort(Comparator.naturalOrder());//正向排序
 42         list.sort( new Comparator<RubikCube>() {
 43             public int compare(RubikCube o1, RubikCube o2) {
 44                 return (int) (o1.solid.getVolume()-o2.solid.getVolume());
 45             }
 46         });
 47         
 48         for(int i = 0; i < list.size(); i++) {
 49             System.out.print(list.get(i).getcolor() + " " + 
 50         String.format("%.2f", list.get(i).solid.getArea()) + " " + 
 51         String.format("%.2f", list.get(i).solid.getVolume()) );
 52             System.out.println("");
 53         }            
 54     }
 55     
 56     public static void display(RubikCube cube)
 57     {
 58         String color = cube.getcolor();
 59         double value1 = cube.solid.getArea();
 60         double value2 = cube.solid.getVolume();
 61         System.out.println(color);
 62         System.out.println(String.format("%.2f",value1));
 63         System.out.println(String.format("%.2f",value2));
 64         
 65     }
 66 }
 67 
 68 abstract class Solid
 69 {
 70     double side = 0;
 71     
 72     public Solid(double side)
 73     {
 74         this.side = side;
 75     }
 76     
 77     abstract double getArea();
 78     
 79     abstract double getVolume();
 80 }
 81 
 82 class Cube extends Solid
 83 {
 84     public Cube(double side) {
 85         super(side);
 86     }
 87 
 88     double getArea()
 89     {
 90         return this.side*this.side*6;
 91     }
 92     
 93     double getVolume()
 94     {
 95         return this.side*this.side*this.side;
 96     }
 97 }
 98 
 99 class RegularPyramid extends Solid
100 {
101 
102     public RegularPyramid(double side) {
103         super(side);
104         // TODO Auto-generated constructor stub
105     }
106     
107     double getArea()
108     {
109         return this.side*this.side*Math.sqrt(3);
110     }
111     
112     double getVolume()
113     {
114         return this.side*this.side*this.side*Math.sqrt(2)/12;
115     }
116 }
117 
118 abstract class RubikCube
119 {
120     String color;
121     int layer;
122     Solid solid;
123     
124     public RubikCube(String color,int layer,Solid solid)
125     {
126         this.color = color;
127         this.layer = layer;
128         this.solid = solid;
129     }
130     
131     String getcolor()
132     {
133         return color;
134     }
135 }
136 
137 class SquareCube extends RubikCube
138 {
139 
140     public SquareCube(String color, int layer, Solid solid) {
141         super(color, layer, solid);
142         // TODO Auto-generated constructor stub
143     }
144 }
145 
146 class RegularPyramidCube extends RubikCube
147 {
148 
149     public RegularPyramidCube(String color, int layer, Solid solid) {
150         super(color, layer, solid);
151         // TODO Auto-generated constructor stub
152     }
153 }

    分析:

  本题相较于上一题没有太大的改动,只是增加了排序这一功能。

  我使用ArrayList<RubikCube>来存储魔方对象,然后使用如下代码来排序:

1 list.sort( new Comparator<RubikCube>() {
2             public int compare(RubikCube o1, RubikCube o2) {
3                 return (int) (o1.solid.getVolume()-o2.solid.getVolume());
4             }
5         });

  就可以实现魔方的排序了。

 

  6.题目7-4 销售步枪问题(附加题)

前亚利桑那州境内的一位步枪销售商销售密苏里州制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是销售商在一个月内可销售70个枪机、80个枪托和90个枪管。

根据每个月的销售情况,计算销售商的佣金(提成)算法如下:

  • 不到(含)1000美元的部分为10%;

  • 1000(含)~1800美元的部分为15%;

  • 超过1800美元的部分为20%。

佣金程序生成月份销售报告,汇总销售商的销售总额和佣金。

编程要求:必须符合面向对象编程,且保证类设计的单一职责模式,使用面向过程编程判定0分。

提示:可以设置一个销售订单类。参考类图如下:

image.png

输入格式:

输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。

输出格式:

分别输出销售商在该月的销售额和佣金,中间用空格分开。

 

  代码如下:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         // TODO Auto-generated method stub
 7         Scanner input = new Scanner(System.in);
 8         
 9         int lnum = input.nextInt();
10         int snum = input.nextInt();
11         int bnum = input.nextInt();
12         
13         SalesOrder sales = new SalesOrder(lnum,snum,bnum);
14         
15         if(lnum<=0||snum<=0||bnum<=0||lnum>70||snum>80||bnum>90)
16             System.out.println("Wrong Format");
17         else
18         {
19             System.out.println(String.format("%.2f", sales.gettotal())+" "+String.format("%.2f", sales.getcom()));
20         }
21     }
22 }
23 
24 class SalesOrder
25 {
26     int locknum;
27     int stocknum;
28     int barrelnum;
29     Lock lock;
30     Stock stock;
31     Barrel barrel;
32     
33     SalesOrder(int locknum,int stocknum, int barrelnum)
34     {
35         this.locknum=locknum;
36         this.stocknum=stocknum;
37         this.barrelnum=barrelnum;
38     }
39     
40     double gettotal()
41     {
42         return locknum*45+stocknum*30+barrelnum*25;
43     }
44     
45     double getcom()
46     {
47         double res = 0;
48         double total = gettotal();
49         if(total<1000)
50             res+=total*0.1;
51         else if(total<1800)
52         {
53             res += 1000*0.1;
54             res += (total-1000)*0.15;
55         }
56         else
57         {
58             res += 1000*0.1;
59             res += 800*0.15;
60             res += (total-1800)*0.2;
61         }
62         
63         return res;
64     }
65 }
66 
67 class Lock
68 {
69     double price ;
70     
71     Lock(double price)
72     {
73         this.price = price;
74     }
75 }
76 
77 class Stock
78 {
79     double price ;
80     
81     Stock(double price)
82     {
83         this.price = price;
84     }
85 }
86 
87 class Barrel
88 {
89     double price ;
90     
91     Barrel(double price)
92     {
93         this.price = price;
94     }
95 }

    分析:

  本题只要写出了lock、stock、barrel类就可以较简便的完成要求。

  本题需要注意的就是关于每个部件销售数量合法性的判断,特别需要注意的就是有些测试用例的销售数量为小于等于0,是不合法的需要特别判断。

 

三、踩坑与修正

  在题目7-2 课程成绩统计程序-3中有一个测试用例较为特殊。由于计算机的精度问题,将87计算成了86.99999。再经过转换成了86,导致结果错误。为了避开这一坑,我将最终成绩初始化为0.00001,这样即避免了这一个坑,也不会影响其他结果。

  这是计算机较为典型的一个错误,由于计算机的存储方式,经常在各种各样的精度问题上会有bug,这个就需要我们来注意。

 

五、总结

  题目集7~8+期末是较为简单的一次作业。

  我在这几周的学习中学到了非常多的java技巧,比如各种各样的模式。

  这几次的题目对我来说是十分有意思的,许多的题目不在是通过超多的逻辑判断来为难我们,而是针对一个一个的知识点来帮助我们学习java,我十分喜欢这样的出题方式,既能帮助已经会的同学复习,也能让不会的同学有参与感,而不是束手无策。

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