目录:
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 立体图形问题
编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。
类结构如下图所示(参考):
试编程完成如上类设计,主方法源码如下(可直接拷贝使用):
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 立体图形问题
问题描述:本问题中的魔方有两种,一种是正方体魔方,一种是正三棱锥魔方,其中,正方体或正三棱锥魔方是由单元正方体或正三棱锥组成,单元正方体或正三棱锥的个数由阶数(即层数)决定,即魔方边长=阶数*单元边长。魔方如下图所示:
利用“立体图形”问题源码,实现如下功能:
魔方有三个属性:颜色,阶数,类型(正方体魔方、正三棱锥魔方),程序要求输出魔方的颜色、表面积和体积。参考设计类图如下所示:
主方法部分可参考如下源码(可拷贝直接使用):
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分。
提示:可以设置一个销售订单类。参考类图如下:
输入格式:
输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。
输出格式:
分别输出销售商在该月的销售额和佣金,中间用空格分开。
代码如下:
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的能力,谢谢各位的耐心观看!
标签:题目,String,int,PTA,空格,期末,input,成绩,side From: https://www.cnblogs.com/AnchunDD/p/17880644.html