关于PTA大作业第三次总结
这一阶段的题目难度更大,而且都是实现某一功能的完整的小程序的题目,让程序设计更加复杂,题目量适中;基本都是在考察继承与多态这两大技术特性;同时还对类的设计有要求;java类的七大设计原则:单一职责原则等。这一阶段的题目主要锻炼对类结构的设计。
2.设计与分析
7-1 课程成绩统计程序-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.text.Collator; 2 import java.util.ArrayList; 3 import java.util.Locale; 4 import java.util.Scanner; 5 import java.util.Collections; 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 ArrayList<Course> courses = new ArrayList<>();//课程清单 10 ArrayList<Student> stu = new ArrayList<>();//学生清单 11 ArrayList<Class> classes = new ArrayList<>();//班级清单 12 while (true) { 13 String string = in.nextLine(); 14 String[] temp = string.split(" "); 15 if (string.contains("end")) { 16 break; 17 } 18 19 else if (temp.length == 2 && temp[1].equals("必修")) {//必修课,省略考核方式 20 boolean flag = false;//判断是否有这门课 没有 21 for(Course e : courses){//不含该课程 22 if(e.getName().equals(temp[0])){//有这门课 23 flag = true; 24 break; 25 } 26 } 27 if(flag == false){//没有这门课 28 Course course = new Course(temp[0], temp[1], "考试");//课程名称,性质,考核方式 29 courses.add(course); 30 } 31 else if(temp[1].equals("选修") ) {//性质为选修 32 System.out.println(temp[0] + " : course type & access mode mismatch"); 33 } 34 } 35 else if (temp.length == 3) {//课程信息 36 boolean flag = false;//设没有这门课 37 for(Course e: courses) { 38 if(e.getName().equals(temp[0])) { 39 flag = true; 40 break; 41 } 42 } 43 if(flag == false) {//没有这门课 44 if((temp[1].equals("必修") && temp [2].equals("考察")) ) {//考试性质 与 考察方式 不匹配 45 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 46 } 47 else {//匹配 48 Course course = new Course(temp[0], temp[1], temp[2]);//课程名称,性质,考核方式 49 courses.add(course); 50 } 51 } 52 } 53 else if (string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}(\\s([\\d]{1,2}|100)){1,2}")) {// 54 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 55 for( i = 0 ; i < classes.size() ; i++){ 56 if(temp[0].contains(classes.get(i).getName())){//找到了班级 57 break; 58 } 59 } 60 if(i == classes.size()){//班级不存在 61 Class class1 = new Class(temp[0].substring(0,6)); 62 classes.add(class1); 63 } 64 for (j = 0; j < classes.get(i).students.size(); j++) { 65 if (classes.get(i).searchStudent(temp[0],temp[1])) { 66 break;//学生存在 67 } 68 } 69 if (j == classes.get(i).students.size()) {//学生不存在 70 Student student = new Student(temp[0],temp[1]); 71 classes.get(i).students.add(student); 72 } 73 if(temp.length == 4){ 74 int flag = 0; 75 for (n = 0; n < courses.size(); n++) {//有这门课 76 if (courses.get(n).getName().equals(temp[2])) { 77 break; 78 } 79 } 80 if (n == courses.size()) {//没有这门课 81 System.out.println(temp[2] + " does not exist"); 82 flag = 1; 83 } 84 if (courses.size() > 0) { 85 int m = 0; 86 if (flag == 0) {//有课的情况 87 if (courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 88 if(courses.get(n).getCourseNature().equals("选修")){ 89 int x = Integer.parseInt(temp[3]); 90 courses.get(n).setScore2(x); 91 courses.get(n).setScore3(x); 92 classes.get(i).getStudents().get(j).setScore3(x); 93 } 94 } else { 95 System.out.println(temp[0] + " " + 96 temp[1] + " : " + "access mode mismatch"); 97 } 98 } 99 } 100 } 101 if(temp.length == 5){ 102 int flag = 0; 103 for (n = 0; n < courses.size(); n++) {//有这门课 104 if (courses.get(n).getName().equals(temp[2])) { 105 break; 106 } 107 } 108 if (n == courses.size()) {//没有这门课 109 System.out.println(temp[2] + " does not exist"); 110 flag = 1; 111 } 112 if (courses.size() > 0) { 113 int m = 0; 114 if (flag == 0) {//有课的情况 115 if (!courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 116 int x = Integer.parseInt(temp[3]); 117 int y = Integer.parseInt(temp[4]); 118 int z = (int)(0.3* x + 0.7 *y); 119 courses.get(n).setScore1(x); 120 courses.get(n).setScore2(y); 121 courses.get(n).setScore3(z); 122 classes.get(i).getStudents().get(j).setScore3(z); 123 124 } else { 125 System.out.println(temp[0] + " " + 126 temp[1] + " : " + "access mode mismatch"); 127 } 128 } 129 } 130 131 } 132 133 134 } 135 else 136 System.out.println("wrong format"); 137 138 } 139 140 Collections.sort(classes); 141 for(Class e:classes){ 142 e.printScore(); 143 } 144 courses.sort((Course o1,Course o2)->{ 145 Collator instance = Collator.getInstance(Locale.CHINA); 146 return instance.compare(o1.getName(),o2.getName()); 147 }); 148 for(Course e : courses){ 149 int n = e.getNum(); 150 if(e.getCourseNature().equals("必修") || e.getCourseNature().equals("选修") && e.getInvestigationMethod().equals("考试")) { 151 if(e.getNum() == 0){ 152 System.out.println(e.getName() + " " +"has no grades yet"); 153 } 154 else 155 System.out.println(e.getName() + " " + e.getScore1()/ n + " " + e.getScore2()/ n+ " " + e.getScore3()/ n); 156 } 157 else { 158 if(e.getNum() == 0){ 159 System.out.println(e.getName() + " "+ "has no grades yet"); 160 } 161 else 162 System.out.println(e.getName() +" " + e.getScore2()/n + " " + e.getScore3()/ n); 163 } 164 } 165 for(Class e:classes){ 166 e.pScore(); 167 } 168 169 } 170 } 171 class Class implements Comparable<Class>{ 172 private String name; 173 ArrayList<Student> students =new ArrayList<>(); 174 public Class(String name) { 175 this.name = name; 176 } 177 public ArrayList<Student> getStudents() { 178 return students; 179 } 180 public String getName() { 181 return name; 182 } 183 public boolean searchStudent(String num,String name){ 184 for(Student e:students){ 185 if(e.getName().equals(name) && e.getStudentNumber().equals(num)) 186 return true; 187 } 188 return false; 189 } 190 public Student getStudent(String num,String name){ 191 for(int i = 0; i<students.size();i++){ 192 if(students.get(i).getName().equals(name) && students.get(i).getStudentNumber().equals(num)) 193 return students.get(i); 194 } 195 return null; 196 } 197 @Override 198 public int compareTo(Class o) { 199 return (int)(this.name.compareTo(o.getName())); 200 } 201 public void printScore(){ 202 Collections.sort(students); 203 for(Student e: students){ 204 e.printScore(); 205 } 206 } 207 public void pScore(){ 208 int sum = 0; 209 for(Student e :students){ 210 sum += e.getScore3(); 211 } 212 int n = 0; 213 for(int i = 0; i < students.size() ; i++){ 214 n = n + students.get(i).getNum(); 215 } 216 if(n != 0) 217 sum = sum / n; 218 if(sum != 0){ 219 System.out.println(name + " " + sum ); 220 } 221 if(sum == 0){ 222 System.out.println(name + " " + "has no grades yet"); 223 } 224 } 225 } 226 class Course { 227 private String name ; 228 private String Nature; 229 private String Method; 230 private int score1 = 0; 231 private int score2 = 0; 232 private int score3 = 0; 233 private Score score; 234 private int num = 0; 235 236 public Course() { 237 } 238 239 public Course(String name, String Nature, String Method) { 240 this.name = name; 241 this.Nature = Nature; 242 this.Method = Method; 243 244 } 245 246 public String getName() { 247 return name; 248 } 249 250 public String getCourseNature() { 251 return Nature; 252 } 253 254 public String getInvestigationMethod() { 255 return Method; 256 } 257 258 259 public int getScore1() { 260 return score1; 261 } 262 263 public void setScore1(int score1) { 264 this.score1 += score1; 265 } 266 267 public int getScore2() { 268 return score2; 269 } 270 271 public void setScore2(int score2) { 272 this.score2 += score2; 273 } 274 275 public int getScore3() { 276 return score3; 277 } 278 public void setScore3(int score3){ 279 this.num++; 280 this.score3 += score3; 281 282 } 283 284 public int getNum() { 285 return num; 286 } 287 288 } 289 class ExamineScore extends Score{ 290 private int totalScore; 291 292 public ExamineScore() { 293 } 294 295 public int getTotalScore() { 296 return totalScore; 297 } 298 299 public void setTotalGrade(int totalScore) { 300 this.totalScore= totalScore; 301 } 302 303 } 304 abstract class Score { 305 private int score1;//平时成绩 306 private int score2;//期末成绩 307 private int score3;//总成绩 308 309 public Score(){ 310 311 } 312 public int getScore1() { 313 return score1; 314 } 315 316 public void setScore1(int score1) { 317 this.score1 = score1; 318 } 319 320 public int getScore2() { 321 return score2; 322 } 323 324 public void setScore2(int score2) { 325 this.score2 = score2; 326 } 327 328 public int getScore3() { 329 return score3; 330 } 331 332 public void setScore3(int score3) { 333 this.score3 = score3; 334 } 335 336 } 337 338 class Student implements Comparable<Student>{ 339 private String name ; 340 private String Number; 341 342 private int score3 = 0; 343 private int num = 0 ; 344 public Student() { 345 346 } 347 public Student(String Number, String name) { 348 this.name = name; 349 this.Number = Number; 350 } 351 public Student(String studentNumber, String name, int score3) { 352 this.name = name; 353 this.Number = studentNumber; 354 this.score3 += score3; 355 if(score3 != 0) 356 this.num++; 357 } 358 public String getName() { 359 return name; 360 } 361 362 public String getStudentNumber() { 363 return Number; 364 } 365 366 public int getScore3() { 367 return score3; 368 } 369 370 public void setScore3(int score3) { 371 if(score3 != 0) 372 num ++; 373 this.score3 += score3; 374 } 375 @Override 376 public int compareTo(Student o) { 377 return (int)(this.getStudentNumber().compareTo(o.getStudentNumber())); 378 } 379 public void printScore(){ 380 381 if(this.num != 0) 382 System.out.println(Number + " " + name + " " + this.score3 / num); 383 else 384 System.out.println(Number + " " + name + " " + "did not take any exams"); 385 } 386 public int getNum() { 387 return num; 388 } 389 } 390 class TestScore extends Score { 391 private int score1; 392 private int score2; 393 private int score3; 394 395 @Override 396 public int getScore1() { 397 return score1; 398 } 399 400 @Override 401 public void setScore1(int score1) { 402 this.score1 = score1; 403 } 404 405 @Override 406 public int getScore2() { 407 return score2; 408 } 409 410 @Override 411 public void setScore2(int score2) { 412 this.score2 = score2; 413 } 414 415 @Override 416 public int getScore3() { 417 return score3; 418 } 419 420 @Override 421 public void setScore3(int score3) { 422 this.score3 = score3; 423 } 424 } 425 class Selection {//选课类 426 private Course course = new Course(); 427 private Student student = new Student(); 428 private Score score; 429 430 public Selection() { 431 } 432 433 public Selection(Course course, Student student, Score score) { 434 this.course = course; 435 this.student = student; 436 this.score = score; 437 } 438 }
生成的类图如下:
这里,主要就是Score类包含了ExaminScore 和 TestScore;然后Class一个班里有很多学生,一个学生有很多门课;这样就可以求得班级的总成绩,学生的总成绩以及每个课程的总成绩;
这里我的题测部分都过了;但是还有一些测试点没过;当时时间也截止了,就没有把错误的改过来。这里我没有对管错误的课程信息,所以就没有过这两个测试点。这里主函数中的代码很长,并且实现的功能很多,并没有实现单一职责原则。
7-1 统计Java程序中关键词的出现次数
分数 100
全屏浏览题目
切换布局
作者 段喜龙
单位 南昌航空大学
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
Java中共有53个关键字(自行百度)
从键盘输入一段源码,统计这段源码中出现的关键字的数量
注释中出现的关键字不用统计
字符串中出现的关键字不用统计
统计出的关键字及数量按照关键字升序进行排序输出
未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
当未输入源码时,程序输出Wrong Format
当没有统计数据时,输出为空
当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字
输入样例:
在这里给出一组输入。例如:
//Test public method
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
exit
输出样例:
在这里给出相应的输出。例如:
1 float
3 if
2 int
2 new
2 public
3 this
2 throw
代码如下:
1 import java.util.*; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 public class Main { 5 public static void main(String[] args) { 6 HashMap<String, Integer> keyWords = new HashMap<>(); 7 Set<String> information = new HashSet<>(); 8 String[] keyWord = {"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while"}; 9 Scanner input = new Scanner(System.in); 10 String str = input.nextLine();//输入的一行 11 StringBuilder line = new StringBuilder(" "); 12 while (!str.equals("exit")) { 13 line.append(str.replaceAll("//.*", " ").replaceAll("\".*\"", " ")); 14 str = input.nextLine(); 15 } 16 str = line.toString(); 17 if (str.length() == 0) { 18 System.out.println("Wrong Format"); 19 return; 20 } 21 str = delete("\"(.*?)\"", str); 22 str = delete("/\\**(.*?)/", str); 23 str = str.replace("=","a"); 24 str = str.replaceAll("[\\pP+~$`^=|<>~`$^+|<>¥×]" , " "); 25 str = str.replaceAll("[^a-zA-Z]", " "); 26 for (int i = 0; i < 53; i++) { 27 Pattern pattern = Pattern.compile("\\b" + keyWord[i] + "\\b"); 28 Matcher matcher = pattern.matcher(str); 29 while (matcher.find()) 30 if (information.contains(keyWord[i])) 31 keyWords.replace(keyWord[i], keyWords.get(keyWord[i]) + 1); 32 else { 33 keyWords.put(keyWord[i], 1); 34 information.add(keyWord[i]); 35 } 36 } 37 Set set = keyWords.keySet(); 38 Object[] arr = set.toArray(); 39 Arrays.sort(arr); 40 for (Object i : arr) 41 System.out.println(keyWords.get(i) + "\t" + i); 42 } 43 public static String delete(String pattern, String str) { 44 Pattern p = Pattern.compile(pattern); 45 Matcher m = p.matcher(str); 46 while (m.find()) { 47 str = str.replace(m.group(), " "); 48 m = p.matcher(str); 49 } 50 return str; 51 } 52 }
这道题是统计给定的源码中java关键字的数量;解题思路是:先把java中53个关键字放在一个字符串数组里,然后对提供的源码进行逐行分析:先判断有没有注释的标记如“//”或“\*”等,用一个容器StringBuilder来存放去掉了注释之后的源码;然后再对剩下的源码进行分析:将所有的非英文字符都换成空格,最后用Pattern来判断是否匹配该种模式。
总的来说,这道题的思路不是很复杂,但是难点在于怎么用代码实现这些相应的功能,要选择相应的容器才能更好地实现这些功能。
7-3 课程成绩统计程序-2
分数 60
全屏浏览题目
切换布局
作者 蔡轲
单位 南昌航空大学
课程成绩统计程序-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.text.Collator; 2 import java.util.ArrayList; 3 import java.util.Collections; 4 import java.util.Locale; 5 import java.util.Scanner; 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 ArrayList<Course> courses = new ArrayList<>();//课程清单 10 ArrayList<Class> classes = new ArrayList<>();//班级清单 11 while (true) { 12 String string = in.nextLine(); 13 String[] temp = string.split(" "); 14 if (string.contains("end")) { 15 break; 16 } 17 18 else if (temp.length == 5 && (temp[1].equals("必修") || temp[1].equals("选修")) && temp[2].equals("考试")) {//考试的课程,选修或必修都行 19 20 boolean flag = false;//判断是否有这门课 没有 21 for(Course e : courses){//不含该课程 22 if(e.getName().equals(temp[0])){//有这门课 23 flag = true; 24 break; 25 } 26 } 27 if(flag == false){//没有这门课 28 double weightSum = 0;//权重和 29 for(int b = 0 ; b < 2 ; b ++){//看权重之和是否为1 30 double h = Double.parseDouble(temp[3 + b]); 31 weightSum += h; 32 } 33 if(!(Math.abs(weightSum - 1.0) <= 0.000001)){//权重之和不为1 34 System.out.println(temp[0] + " : weight value error"); 35 } 36 else { 37 Course course = new Course(temp[0], temp[1], "考试",2);//课程名称,性质,考核方式 38 for(int i = 0 ; i < 2; i++){ 39 course.getScore().getWeight().add(Double.parseDouble(temp[3+i]));//设置权重 40 } 41 courses.add(course); 42 } 43 } 44 45 } 46 else if (temp.length == 3) {//考察的课程 47 boolean flag = false;//设没有这门课 48 for(Course e: courses) { 49 if(e.getName().equals(temp[0])) { 50 flag = true; 51 break; 52 } 53 } 54 if(flag == false) {//没有这门课 55 if((temp[1].equals("必修") && temp [2].equals("考察") ) ) {//考试性质 与 考察方式 不匹配 56 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 57 } 58 else if(temp[1].equals("必修") && temp[2].equals("实验") ){ 59 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 60 } 61 else if(temp[1].equals("选修") && temp[2].equals("实验")){ 62 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 63 } 64 else {//匹配 65 Course course = new Course(temp[0], temp[1], temp[2],1);//课程名称,性质,考核方式,成绩数量 66 course.getScore().getWeight().add(1.0);//设置权重 67 courses.add(course); 68 } 69 } 70 } 71 else if(temp[2].equals("实验") && temp[1].equals("实验") && string.matches("(([\\u4e00-\\u9fa5[\\w]]){1,10}\\s)实验\\s实验\\s[4-9](\\s0\\.\\d+)+") ){//实验课程的处理 72 int num = Integer.parseInt(temp[3]);//次数 73 boolean flag = false;//设没有这门课 74 for(Course e: courses) { 75 if(e.getName().equals(temp[0])) { 76 flag = true; 77 break; 78 } 79 } 80 if(flag == false){ 81 if(temp.length == (4 + num)){//权重数量匹配 82 double weightSum = 0; 83 for(int b = 0 ; b < num ; b ++){//看权重之和是否为1 84 double h = Double.parseDouble(temp[4 + b]); 85 weightSum += h; 86 } 87 if(!(Math.abs(weightSum - 1.0) < 0.000001)){//权重之和不为1 88 System.out.println(temp[0] + " : weight value error"); 89 } 90 else { 91 Course course = new Course(temp[0],temp[1],temp[2],Integer.parseInt(temp[3])); 92 for(int i = 0; i < num ; i ++){ 93 course.getScore().getWeight().add(Double.parseDouble(temp[4+i]));//设置权重 94 } 95 courses.add(course); 96 } 97 } 98 else{//数量不匹配 99 System.out.println(temp[0] + " : number of scores does not match");//数量不匹配 100 } 101 } 102 } 103 else if (string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}(\\s([\\d]{1,2}|100)){1,2}")) {//选修必修课程成绩处理 104 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 105 for( i = 0 ; i < classes.size() ; i++){ 106 if(temp[0].contains(classes.get(i).getName())){//找到了班级 107 break; 108 } 109 } 110 if(i == classes.size()){//班级不存在 111 Class class1 = new Class(temp[0].substring(0,6)); 112 classes.add(class1); 113 } 114 for (j = 0; j < classes.get(i).students.size(); j++) { 115 if (classes.get(i).searchStudent(temp[0],temp[1])) { 116 break;//学生存在 117 } 118 } 119 if (j == classes.get(i).students.size()) {//学生不存在 120 Student student = new Student(temp[0],temp[1]); 121 classes.get(i).students.add(student); 122 } 123 if(temp.length == 4){//选修课 124 int flag = 0; 125 for (n = 0; n < courses.size(); n++) {//有这门课 126 if (courses.get(n).getName().equals(temp[2])) { 127 break; 128 } 129 } 130 if (n == courses.size()) {//没有这门课 131 System.out.println(temp[2] + " does not exist"); 132 flag = 1; 133 } 134 if (courses.size() > 0) { 135 int m = 0; 136 if (flag == 0) {//有课的情况 137 if (courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 138 if(courses.get(n).getCourseNature().equals("选修")){ 139 double x = Double.parseDouble(temp[3]);//选修的成绩 140 courses.get(n).getScore().getScores().add(x); 141 // courses.get(n).setScore3(x); 142 courses.get(n).getSumScore(); 143 classes.get(i).getStudents().get(j).setScore3(x); 144 145 } 146 } else { 147 System.out.println(temp[0] + " " + 148 temp[1] + " : " + "access mode mismatch"); 149 } 150 } 151 } 152 } 153 if(temp.length == 5){//选修 或 必修的考试 154 int flag = 0; 155 for (n = 0; n < courses.size(); n++) {//有这门课 156 if (courses.get(n).getName().equals(temp[2])) { 157 break; 158 } 159 } 160 if (n == courses.size()) {//没有这门课 161 System.out.println(temp[2] + " does not exist"); 162 flag = 1; 163 } 164 if (courses.size() > 0) { 165 int m = 0; 166 if (flag == 0) {//有课的情况 167 if (!courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 168 double x = Double.parseDouble(temp[3]); 169 double y = Double.parseDouble(temp[4]); 170 // 171 courses.get(n).getScore().getScores().add(x); 172 courses.get(n).getScore().getScores().add(y); 173 // 174 courses.get(n).getSumScore(); 175 classes.get(i).getStudents().get(j).setScore3(courses.get(n).getScore().getSum()); 176 courses.get(n).getScore().getScores().clear(); 177 } else { 178 System.out.println(temp[0] + " " + 179 temp[1] + " : " + "access mode mismatch"); 180 } 181 } 182 } 183 184 } 185 } 186 else if(string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5[\\w]]){1,10}){2}(\\s([\\d]{1,2}|100))+")){//实验成绩的处理 187 int num = 0; 188 for(int p = 0 ; p < courses.size() ; p++){ 189 if(courses.get(p).getName().equals(temp[2])){//有这门课 190 num = courses.get(p).getScore().getWeight().size();//成绩数量 191 } 192 } 193 //int num= Integer.parseInt(temp[3]);//出现的次数 194 if(temp.length - 3 == num){//成绩数量匹配 195 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 196 for( i = 0 ; i < classes.size() ; i++){ 197 if(temp[0].contains(classes.get(i).getName())){//找到了班级 198 break; 199 } 200 } 201 if(i == classes.size()){//班级不存在 202 Class class1 = new Class(temp[0].substring(0,6)); 203 classes.add(class1); 204 } 205 for (j = 0; j < classes.get(i).students.size(); j++) { 206 if (classes.get(i).searchStudent(temp[0],temp[1])) { 207 break;//学生存在 208 } 209 } 210 if (j == classes.get(i).students.size()) {//学生不存在 211 Student student = new Student(temp[0],temp[1]); 212 classes.get(i).students.add(student); 213 } 214 int flag = 0;//判断有没有课 215 for (n = 0; n < courses.size(); n++) {//有这门课 216 if (courses.get(n).getName().equals(temp[2])) { 217 break; 218 } 219 } 220 if (n == courses.size()) {//没有这门课 221 System.out.println(temp[2] + " does not exist"); 222 flag = 1; 223 } 224 if (courses.size() > 0) { 225 int m = 0; 226 if (flag == 0) {//有课的情况 227 if (courses.get(n).getInvestigationMethod().equals("实验")) {//这节课的 228 if(courses.get(n).getCourseNature().equals("实验")){ 229 for (int a = 0 ; a < num ; a ++){ 230 courses.get(n).getScore().getScores().add(Double.parseDouble(temp[3 + a])); 231 } 232 courses.get(n).getSumScore(); 233 classes.get(i).getStudents().get(j).setScore3(courses.get(n).getScore().getSum()); 234 courses.get(n).getScore().getScores().clear(); 235 } 236 } 237 else { 238 System.out.println(temp[0] + " " + 239 temp[1] + " : " + "access mode mismatch"); 240 } 241 } 242 } 243 } 244 else {//成绩数量不匹配 245 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 246 for( i = 0 ; i < classes.size() ; i++){ 247 if(temp[0].contains(classes.get(i).getName())){//找到了班级 248 break; 249 } 250 } 251 if(i == classes.size()){//班级不存在 252 Class class1 = new Class(temp[0].substring(0,6)); 253 classes.add(class1); 254 } 255 for (j = 0; j < classes.get(i).students.size(); j++) { 256 if (classes.get(i).searchStudent(temp[0],temp[1])) { 257 break;//学生存在 258 } 259 } 260 if (j == classes.get(i).students.size()) {//学生不存在 261 Student student = new Student(temp[0],temp[1]); 262 classes.get(i).students.add(student); 263 } 264 int flag = 0;//判断有没有课 265 for (n = 0; n < courses.size(); n++) {//有这门课 266 if (courses.get(n).getName().equals(temp[2])) { 267 System.out.println(temp[0] + " " + 268 temp[1] + " : " + "access mode mismatch"); 269 break; 270 } 271 } 272 if (n == courses.size()) {//没有这门课 273 System.out.println(temp[2] + " does not exist"); 274 flag = 1; 275 } 276 } 277 } 278 else 279 System.out.println("wrong format"); 280 } 281 282 Collections.sort(classes); 283 284 for(Class e:classes){ 285 e.printScore(); 286 } 287 courses.sort((Course o1,Course o2)->{ 288 Collator instance = Collator.getInstance(Locale.CHINA); 289 return instance.compare(o1.getName(),o2.getName()); 290 }); 291 for(Course e : courses){ 292 int n = e.getNum(); 293 if(e.getCourseNature().equals("必修") || e.getCourseNature().equals("选修") && e.getInvestigationMethod().equals("考试")) { 294 if(e.getNum() == 0){ 295 System.out.println(e.getName() + " " +"has no grades yet"); 296 } 297 else 298 System.out.println(e.getName() + " " + e.getGrade()); 299 } 300 else if(e.getCourseNature().equals("实验") && e.getInvestigationMethod().equals("实验")){//实验成绩的输出 301 if(e.getNum() == 0){ 302 System.out.println(e.getName() + " " + "has no grades yet"); 303 } 304 else 305 System.out.println(e.getName() + " " + e.getGrade()); 306 } 307 else { 308 if(e.getNum() == 0){ 309 System.out.println(e.getName() + " "+ "has no grades yet"); 310 } 311 else 312 System.out.println(e.getName() +" " + e.getGrade()); 313 } 314 } 315 for(Class e:classes){ 316 e.pScore(); 317 } 318 319 } 320 } 321 class Class implements Comparable<Class>{ 322 private String name; 323 ArrayList<Student> students =new ArrayList<>(); 324 public Class(String name) { 325 this.name = name; 326 } 327 public ArrayList<Student> getStudents() { 328 return students; 329 } 330 public String getName() { 331 return name; 332 } 333 public boolean searchStudent(String num,String name){ 334 for(Student e:students){ 335 if(e.getName().equals(name) && e.getStudentNumber().equals(num)) 336 return true; 337 } 338 return false; 339 } 340 public Student getStudent(String num,String name){ 341 for(int i = 0; i<students.size();i++){ 342 if(students.get(i).getName().equals(name) && students.get(i).getStudentNumber().equals(num)) 343 return students.get(i); 344 } 345 return null; 346 } 347 @Override 348 public int compareTo(Class o) { 349 return (int)(this.name.compareTo(o.getName())); 350 } 351 public void printScore(){ 352 Collections.sort(students); 353 for(Student e: students){ 354 e.printScore(); 355 } 356 } 357 public void pScore(){//输出班级的分数 358 int sum = 0; 359 for(Student e :students){ 360 sum += e.getScore3(); 361 } 362 int n = 0; 363 for(int i = 0; i < students.size() ; i++){ 364 n = n + students.get(i).getNum(); 365 } 366 if(n != 0) 367 sum = sum / n; 368 if(sum != 0){ 369 System.out.println(name + " " + sum ); 370 } 371 if(sum == 0){ 372 System.out.println(name + " " + "has no grades yet"); 373 } 374 } 375 } 376 class Course { 377 private String name ; 378 private String Nature; 379 private String Method; 380 private double sumScore; 381 private Score score = new Score(); 382 private int num = 0;//该课程学生的数量 383 384 public Course() { 385 } 386 387 public Course(String name, String Nature, String Method,int n) { 388 this.name = name; 389 this.Nature = Nature; 390 this.Method = Method; 391 this.score.setN(n); 392 } 393 394 public String getName() { 395 return name; 396 } 397 398 public String getCourseNature() { 399 return Nature; 400 } 401 402 public String getInvestigationMethod() { 403 return Method; 404 } 405 406 407 public Score getScore() { 408 return score; 409 } 410 411 public int getNum() { 412 return num; 413 } 414 415 public double getSumScore() { 416 sumScore += this.score.getSum(); 417 this.num++; 418 return this.sumScore; 419 } 420 421 public void setSumScore(double sumScore) { 422 this.sumScore =(int) sumScore; 423 } 424 public int getGrade(){ 425 426 return (int)(this.sumScore) / this.num; 427 } 428 } 429 class ExamineScore extends Score{ 430 private int totalScore; 431 432 public ExamineScore() { 433 } 434 435 public int getTotalScore() { 436 return totalScore; 437 } 438 439 public void setTotalGrade(int totalScore) { 440 this.totalScore= totalScore; 441 } 442 443 } 444 class Score { 445 int n = 0;//成绩数量 446 ArrayList<Double> scores = new ArrayList<>();//分项成绩 447 ArrayList<Double> weight = new ArrayList<>();//权重 448 private double sum = 0; 449 public Score(){ 450 451 } 452 453 public Score(int n) { 454 this.n = n; 455 } 456 457 public int getN() { 458 return n; 459 } 460 461 public void setN(int n) { 462 this.n = n; 463 } 464 465 public ArrayList<Double> getScores() { 466 return scores; 467 } 468 469 public void setScores(ArrayList<Double> scores) { 470 this.scores = scores; 471 } 472 473 public ArrayList<Double> getWeight() { 474 return weight; 475 } 476 477 public void setWeight(ArrayList<Double> weight) { 478 this.weight = weight; 479 } 480 481 public double getSum(){ 482 this.sum = 0; 483 if(n != 0) 484 for(int i = 0 ; i < n ; i ++){ 485 sum += scores.get(i) * weight.get(i); 486 } 487 return sum; 488 } 489 } 490 491 class Student implements Comparable<Student>{ 492 private String name ; 493 private String Number; 494 495 private double score3 = 0; 496 private int num = 0 ; 497 public Student() { 498 499 } 500 public Student(String Number, String name) { 501 this.name = name; 502 this.Number = Number; 503 } 504 public Student(String studentNumber, String name, int score3) { 505 this.name = name; 506 this.Number = studentNumber; 507 this.score3 += score3; 508 if(score3 != 0) 509 this.num++; 510 } 511 public String getName() { 512 return name; 513 } 514 515 public String getStudentNumber() { 516 return Number; 517 } 518 519 public double getScore3() { 520 return score3; 521 } 522 523 public void setScore3(double score3) { 524 if(score3 != 0) 525 num ++; 526 this.score3 += score3; 527 } 528 @Override 529 public int compareTo(Student o) { 530 return (int)(this.getStudentNumber().compareTo(o.getStudentNumber())); 531 } 532 public void printScore(){ 533 534 if(this.num != 0) 535 System.out.println(Number + " " + name + " " + (int)(this.score3) / num); 536 else 537 System.out.println(Number + " " + name + " " + "did not take any exams"); 538 } 539 public int getNum() { 540 return num; 541 } 542 } 543 class TestScore extends Score { 544 private int score1; 545 private int score2; 546 private int score3; 547 548 549 } 550 class Selection {//选课类 551 private Course course = new Course(); 552 private Student student = new Student(); 553 private Score score; 554 555 public Selection() { 556 } 557 558 public Selection(Course course, Student student, Score score) { 559 this.course = course; 560 this.student = student; 561 this.score = score; 562 } 563 }
这道题在之前题目的基础上,添加了实验课这门课程,但是题目的测试点少了很多异常情况,总体难度我感觉比第一次的难度下降了。题目的重点在于正则表达式的使用,如何利用正则表达式快速地区分各种情况;例如
这是我在题目中对实验成绩的处理;用一个正则表达式来判断是否满足实验成绩的格式。
总体的情况与第一次相比就是在课程方面多加了一个实验课,其他的情况都差不多。
7-2 课程成绩统计程序-3
分数 64
全屏浏览题目
切换布局
作者 蔡轲
单位 南昌航空大学
课程成绩统计程序-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.text.Collator; 2 import java.util.ArrayList; 3 import java.util.Collections; 4 import java.util.Locale; 5 import java.util.Scanner; 6 public class Main { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 ArrayList<Course> courses = new ArrayList<>();//课程清单 10 ArrayList<Class> classes = new ArrayList<>();//班级清单 11 while (true) { 12 String string = in.nextLine(); 13 String[] temp = string.split(" "); 14 if (string.contains("end")) { 15 break; 16 } 17 18 else if (temp.length == 5 && (temp[1].equals("必修") || temp[1].equals("选修")) && temp[2].equals("考试")) {//考试的课程,选修或必修都行 19 20 boolean flag = false;//判断是否有这门课 没有 21 for(Course e : courses){//不含该课程 22 if(e.getName().equals(temp[0])){//有这门课 23 flag = true; 24 break; 25 } 26 } 27 if(flag == false){//没有这门课 28 double weightSum = 0;//权重和 29 for(int b = 0 ; b < 2 ; b ++){//看权重之和是否为1 30 double h = Double.parseDouble(temp[3 + b]); 31 weightSum += h; 32 } 33 if(!(Math.abs(weightSum - 1.0) <= 0.000001)){//权重之和不为1 34 System.out.println(temp[0] + " : weight value error"); 35 } 36 else { 37 Course course = new Course(temp[0], temp[1], "考试",2);//课程名称,性质,考核方式 38 for(int i = 0 ; i < 2; i++){ 39 course.getScore().getWeight().add(Double.parseDouble(temp[3+i]));//设置权重 40 } 41 courses.add(course); 42 } 43 } 44 45 } 46 else if (temp.length == 3) {//考察的课程 47 boolean flag = false;//设没有这门课 48 for(Course e: courses) { 49 if(e.getName().equals(temp[0])) { 50 flag = true; 51 break; 52 } 53 } 54 if(flag == false) {//没有这门课 55 if((temp[1].equals("必修") && temp [2].equals("考察") ) ) {//考试性质 与 考察方式 不匹配 56 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 57 } 58 else if(temp[1].equals("必修") && temp[2].equals("实验") ){ 59 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 60 } 61 else if(temp[1].equals("选修") && temp[2].equals("实验")){ 62 System.out.println(temp[0] + " : course type & access mode mismatch");//不匹配 63 } 64 else {//匹配 65 Course course = new Course(temp[0], temp[1], temp[2],1);//课程名称,性质,考核方式,成绩数量 66 course.getScore().getWeight().add(1.0);//设置权重 67 courses.add(course); 68 } 69 } 70 } 71 else if(temp[2].equals("实验") && temp[1].equals("实验") && string.matches("(([\\u4e00-\\u9fa5[\\w]]){1,10}\\s)实验\\s实验\\s[4-9](\\s0\\.\\d+)+") ){//实验课程的处理 72 int num = Integer.parseInt(temp[3]);//次数 73 boolean flag = false;//设没有这门课 74 for(Course e: courses) { 75 if(e.getName().equals(temp[0])) { 76 flag = true; 77 break; 78 } 79 } 80 if(flag == false){ 81 if(temp.length == (4 + num)){//权重数量匹配 82 double weightSum = 0; 83 for(int b = 0 ; b < num ; b ++){//看权重之和是否为1 84 double h = Double.parseDouble(temp[4 + b]); 85 weightSum += h; 86 } 87 if(!(Math.abs(weightSum - 1.0) < 0.000001)){//权重之和不为1 88 System.out.println(temp[0] + " : weight value error"); 89 } 90 else { 91 Course course = new Course(temp[0],temp[1],temp[2],Integer.parseInt(temp[3])); 92 for(int i = 0; i < num ; i ++){ 93 course.getScore().getWeight().add(Double.parseDouble(temp[4+i]));//设置权重 94 } 95 courses.add(course); 96 } 97 } 98 else{//数量不匹配 99 System.out.println(temp[0] + " : number of scores does not match");//数量不匹配 100 } 101 } 102 } 103 else if (string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}(\\s([\\d]{1,2}|100)){1,2}")) {//选修必修课程成绩处理 104 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 105 for( i = 0 ; i < classes.size() ; i++){ 106 if(temp[0].contains(classes.get(i).getName())){//找到了班级 107 break; 108 } 109 } 110 if(i == classes.size()){//班级不存在 111 Class class1 = new Class(temp[0].substring(0,6)); 112 classes.add(class1); 113 } 114 for (j = 0; j < classes.get(i).students.size(); j++) { 115 if (classes.get(i).searchStudent(temp[0],temp[1])) { 116 break;//学生存在 117 } 118 } 119 if (j == classes.get(i).students.size()) {//学生不存在 120 Student student = new Student(temp[0],temp[1]); 121 classes.get(i).students.add(student); 122 } 123 if(temp.length == 4){//选修课 124 int flag = 0; 125 for (n = 0; n < courses.size(); n++) {//有这门课 126 if (courses.get(n).getName().equals(temp[2])) { 127 break; 128 } 129 } 130 if (n == courses.size()) {//没有这门课 131 System.out.println(temp[2] + " does not exist"); 132 flag = 1; 133 } 134 if (courses.size() > 0) { 135 int m = 0; 136 if (flag == 0) {//有课的情况 137 if (courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 138 if(courses.get(n).getCourseNature().equals("选修")){ 139 double x = Double.parseDouble(temp[3]);//选修的成绩 140 courses.get(n).getScore().getScores().add(x); 141 // courses.get(n).setScore3(x); 142 courses.get(n).getSumScore(); 143 classes.get(i).getStudents().get(j).setScore3(x); 144 145 } 146 } else { 147 System.out.println(temp[0] + " " + 148 temp[1] + " : " + "access mode mismatch"); 149 } 150 } 151 } 152 } 153 if(temp.length == 5){//选修 或 必修的考试 154 int flag = 0; 155 for (n = 0; n < courses.size(); n++) {//有这门课 156 if (courses.get(n).getName().equals(temp[2])) { 157 break; 158 } 159 } 160 if (n == courses.size()) {//没有这门课 161 System.out.println(temp[2] + " does not exist"); 162 flag = 1; 163 } 164 if (courses.size() > 0) { 165 int m = 0; 166 if (flag == 0) {//有课的情况 167 if (!courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 168 double x = Double.parseDouble(temp[3]); 169 double y = Double.parseDouble(temp[4]); 170 // 171 courses.get(n).getScore().getScores().add(x); 172 courses.get(n).getScore().getScores().add(y); 173 // 174 courses.get(n).getSumScore(); 175 classes.get(i).getStudents().get(j).setScore3(courses.get(n).getScore().getSum()); 176 courses.get(n).getScore().getScores().clear(); 177 } else { 178 System.out.println(temp[0] + " " + 179 temp[1] + " : " + "access mode mismatch"); 180 } 181 } 182 } 183 184 } 185 } 186 else if(string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5[\\w]]){1,10}){2}(\\s([\\d]{1,2}|100))+")){//实验成绩的处理 187 int num = 0; 188 for(int p = 0 ; p < courses.size() ; p++){ 189 if(courses.get(p).getName().equals(temp[2])){//有这门课 190 num = courses.get(p).getScore().getWeight().size();//成绩数量 191 } 192 } 193 //int num= Integer.parseInt(temp[3]);//出现的次数 194 if(temp.length - 3 == num){//成绩数量匹配 195 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 196 for( i = 0 ; i < classes.size() ; i++){ 197 if(temp[0].contains(classes.get(i).getName())){//找到了班级 198 break; 199 } 200 } 201 if(i == classes.size()){//班级不存在 202 Class class1 = new Class(temp[0].substring(0,6)); 203 classes.add(class1); 204 } 205 for (j = 0; j < classes.get(i).students.size(); j++) { 206 if (classes.get(i).searchStudent(temp[0],temp[1])) { 207 break;//学生存在 208 } 209 } 210 if (j == classes.get(i).students.size()) {//学生不存在 211 Student student = new Student(temp[0],temp[1]); 212 classes.get(i).students.add(student); 213 } 214 int flag = 0;//判断有没有课 215 for (n = 0; n < courses.size(); n++) {//有这门课 216 if (courses.get(n).getName().equals(temp[2])) { 217 break; 218 } 219 } 220 if (n == courses.size()) {//没有这门课 221 System.out.println(temp[2] + " does not exist"); 222 flag = 1; 223 } 224 if (courses.size() > 0) { 225 int m = 0; 226 if (flag == 0) {//有课的情况 227 if (courses.get(n).getInvestigationMethod().equals("实验")) {//这节课的 228 if(courses.get(n).getCourseNature().equals("实验")){ 229 for (int a = 0 ; a < num ; a ++){ 230 courses.get(n).getScore().getScores().add(Double.parseDouble(temp[3 + a])); 231 } 232 courses.get(n).getSumScore(); 233 classes.get(i).getStudents().get(j).setScore3(courses.get(n).getScore().getSum()); 234 courses.get(n).getScore().getScores().clear(); 235 } 236 } 237 else { 238 System.out.println(temp[0] + " " + 239 temp[1] + " : " + "access mode mismatch"); 240 } 241 } 242 } 243 } 244 else {//成绩数量不匹配 245 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 246 for( i = 0 ; i < classes.size() ; i++){ 247 if(temp[0].contains(classes.get(i).getName())){//找到了班级 248 break; 249 } 250 } 251 if(i == classes.size()){//班级不存在 252 Class class1 = new Class(temp[0].substring(0,6)); 253 classes.add(class1); 254 } 255 for (j = 0; j < classes.get(i).students.size(); j++) { 256 if (classes.get(i).searchStudent(temp[0],temp[1])) { 257 break;//学生存在 258 } 259 } 260 if (j == classes.get(i).students.size()) {//学生不存在 261 Student student = new Student(temp[0],temp[1]); 262 classes.get(i).students.add(student); 263 } 264 int flag = 0;//判断有没有课 265 for (n = 0; n < courses.size(); n++) {//有这门课 266 if (courses.get(n).getName().equals(temp[2])) { 267 System.out.println(temp[0] + " " + 268 temp[1] + " : " + "access mode mismatch"); 269 break; 270 } 271 } 272 if (n == courses.size()) {//没有这门课 273 System.out.println(temp[2] + " does not exist"); 274 flag = 1; 275 } 276 } 277 } 278 else 279 System.out.println("wrong format"); 280 } 281 282 Collections.sort(classes); 283 284 for(Class e:classes){ 285 e.printScore(); 286 } 287 courses.sort((Course o1,Course o2)->{ 288 Collator instance = Collator.getInstance(Locale.CHINA); 289 return instance.compare(o1.getName(),o2.getName()); 290 }); 291 for(Course e : courses){ 292 int n = e.getNum(); 293 if(e.getCourseNature().equals("必修") || e.getCourseNature().equals("选修") && e.getInvestigationMethod().equals("考试")) { 294 if(e.getNum() == 0){ 295 System.out.println(e.getName() + " " +"has no grades yet"); 296 } 297 else 298 System.out.println(e.getName() + " " + e.getGrade()); 299 } 300 else if(e.getCourseNature().equals("实验") && e.getInvestigationMethod().equals("实验")){//实验成绩的输出 301 if(e.getNum() == 0){ 302 System.out.println(e.getName() + " " + "has no grades yet"); 303 } 304 else 305 System.out.println(e.getName() + " " + e.getGrade()); 306 } 307 else { 308 if(e.getNum() == 0){ 309 System.out.println(e.getName() + " "+ "has no grades yet"); 310 } 311 else 312 System.out.println(e.getName() +" " + e.getGrade()); 313 } 314 } 315 for(Class e:classes){ 316 e.pScore(); 317 } 318 319 } 320 } 321 class Class implements Comparable<Class>{ 322 private String name; 323 ArrayList<Student> students =new ArrayList<>(); 324 public Class(String name) { 325 this.name = name; 326 } 327 public ArrayList<Student> getStudents() { 328 return students; 329 } 330 public String getName() { 331 return name; 332 } 333 public boolean searchStudent(String num,String name){ 334 for(Student e:students){ 335 if(e.getName().equals(name) && e.getStudentNumber().equals(num)) 336 return true; 337 } 338 return false; 339 } 340 public Student getStudent(String num,String name){ 341 for(int i = 0; i<students.size();i++){ 342 if(students.get(i).getName().equals(name) && students.get(i).getStudentNumber().equals(num)) 343 return students.get(i); 344 } 345 return null; 346 } 347 @Override 348 public int compareTo(Class o) { 349 return (int)(this.name.compareTo(o.getName())); 350 } 351 public void printScore(){ 352 Collections.sort(students); 353 for(Student e: students){ 354 e.printScore(); 355 } 356 } 357 public void pScore(){//输出班级的分数 358 int sum = 0; 359 for(Student e :students){ 360 sum += e.getScore3(); 361 } 362 int n = 0; 363 for(int i = 0; i < students.size() ; i++){ 364 n = n + students.get(i).getNum(); 365 } 366 if(n != 0) 367 sum = sum / n; 368 if(sum != 0){ 369 System.out.println(name + " " + sum ); 370 } 371 if(sum == 0){ 372 System.out.println(name + " " + "has no grades yet"); 373 } 374 } 375 } 376 class Course { 377 private String name ; 378 private String Nature; 379 private String Method; 380 private double sumScore; 381 private Score score = new Score(); 382 private int num = 0;//该课程学生的数量 383 384 public Course() { 385 } 386 387 public Course(String name, String Nature, String Method,int n) { 388 this.name = name; 389 this.Nature = Nature; 390 this.Method = Method; 391 this.score.setN(n); 392 } 393 394 public String getName() { 395 return name; 396 } 397 398 public String getCourseNature() { 399 return Nature; 400 } 401 402 public String getInvestigationMethod() { 403 return Method; 404 } 405 406 407 public Score getScore() { 408 return score; 409 } 410 411 public int getNum() { 412 return num; 413 } 414 415 public double getSumScore() { 416 sumScore += this.score.getSum(); 417 this.num++; 418 return this.sumScore; 419 } 420 421 public void setSumScore(double sumScore) { 422 this.sumScore =(int) sumScore; 423 } 424 public int getGrade(){ 425 426 return (int)(this.sumScore) / this.num; 427 } 428 } 429 class ExamineScore extends Score{ 430 private int totalScore; 431 432 public ExamineScore() { 433 } 434 435 public int getTotalScore() { 436 return totalScore; 437 } 438 439 public void setTotalGrade(int totalScore) { 440 this.totalScore= totalScore; 441 } 442 443 } 444 class Score { 445 int n = 0;//成绩数量 446 ArrayList<Double> scores = new ArrayList<>();//分项成绩 447 ArrayList<Double> weight = new ArrayList<>();//权重 448 private double sum = 0; 449 public Score(){ 450 451 } 452 453 public Score(int n) { 454 this.n = n; 455 } 456 457 public int getN() { 458 return n; 459 } 460 461 public void setN(int n) { 462 this.n = n; 463 } 464 465 public ArrayList<Double> getScores() { 466 return scores; 467 } 468 469 public void setScores(ArrayList<Double> scores) { 470 this.scores = scores; 471 } 472 473 public ArrayList<Double> getWeight() { 474 return weight; 475 } 476 477 public void setWeight(ArrayList<Double> weight) { 478 this.weight = weight; 479 } 480 481 public double getSum(){ 482 this.sum = 0; 483 if(n != 0) 484 for(int i = 0 ; i < n ; i ++){ 485 sum += scores.get(i) * weight.get(i); 486 } 487 return sum; 488 } 489 } 490 491 class Student implements Comparable<Student>{ 492 private String name ; 493 private String Number; 494 495 private double score3 = 0; 496 private int num = 0 ; 497 public Student() { 498 499 } 500 public Student(String Number, String name) { 501 this.name = name; 502 this.Number = Number; 503 } 504 public Student(String studentNumber, String name, int score3) { 505 this.name = name; 506 this.Number = studentNumber; 507 this.score3 += score3; 508 if(score3 != 0) 509 this.num++; 510 } 511 public String getName() { 512 return name; 513 } 514 515 public String getStudentNumber() { 516 return Number; 517 } 518 519 public double getScore3() { 520 return score3; 521 } 522 523 public void setScore3(double score3) { 524 if(score3 != 0) 525 num ++; 526 this.score3 += score3; 527 } 528 @Override 529 public int compareTo(Student o) { 530 return (int)(this.getStudentNumber().compareTo(o.getStudentNumber())); 531 } 532 public void printScore(){ 533 534 if(this.num != 0) 535 System.out.println(Number + " " + name + " " + (int)(this.score3) / num); 536 else 537 System.out.println(Number + " " + name + " " + "did not take any exams"); 538 } 539 public int getNum() { 540 return num; 541 } 542 } 543 class TestScore extends Score { 544 private int score1; 545 private int score2; 546 private int score3; 547 548 549 } 550 class Selection {//选课类 551 private Course course = new Course(); 552 private Student student = new Student(); 553 private Score score; 554 555 public Selection() { 556 } 557 558 public Selection(Course course, Student student, Score score) { 559 this.course = course; 560 this.student = student; 561 this.score = score; 562 } 563 }
题目要求将类结构由继承改为组合的结构,并且新增了权重和分值的概念。这里我的思路是在成绩类中添加分值和权重两个属性,并且分别放在一个ArrayList里面,这样就能一对一地进行分数的计算。新增了异常:权重之和等于1。但是因为权重都是浮点数,所以改为权重之和与1作差后要小于一个很小的数。而其他情况与上一次相比没有多加其他的异常。题目重点也在于正则表达式的使用,利用正则表达式来快速区分各种成绩情况。
3.踩坑心得
1.没有利用正则表达式,我一开始写第一次额作业时没有想过用正则表达式:
而是根据长度来判断,导致我第一次提交时,只有一点点分。而用了正则表达式之后就可以很清楚地分明各个情况。所以要常常使用正则表达式,来更清楚地判断各个情况。
2. 对异常的判断错误。有的时候明明要输出java has no grades yet这句话,可是我的程序却会输出Wrong Format.这就是对异常的判断有问题。这些问题往往都要在某一种情况种新添对异常的判定,或者是多加或者少加一个if语句。
4 .改进建议
1.题目集一:应该注意类与类之间的关系,实现单一职责原则,这样才能更利于程序的维护和调试。
2.题目集二:
相应代码如下:
1 if (string.matches("[\\d]{8}(\\s([\\u4e00-\\u9fa5]|[\\w]){1,10}){2}(\\s([\\d]{1,2}|100)){1,2}")) {//选修必修课程成绩处理 2 int i ,n ,j = 0;// i 是班级的下标 j是班级中 学生的线下标 n是课程的下标 3 for( i = 0 ; i < classes.size() ; i++){ 4 if(temp[0].contains(classes.get(i).getName())){//找到了班级 5 break; 6 } 7 } 8 if(i == classes.size()){//班级不存在 9 Class class1 = new Class(temp[0].substring(0,6)); 10 classes.add(class1); 11 } 12 for (j = 0; j < classes.get(i).students.size(); j++) { 13 if (classes.get(i).searchStudent(temp[0],temp[1])) { 14 break;//学生存在 15 } 16 } 17 if (j == classes.get(i).students.size()) {//学生不存在 18 Student student = new Student(temp[0],temp[1]); 19 classes.get(i).students.add(student); 20 } 21 if(temp.length == 4){//选修课 22 int flag = 0; 23 for (n = 0; n < courses.size(); n++) {//有这门课 24 if (courses.get(n).getName().equals(temp[2])) { 25 break; 26 } 27 } 28 if (n == courses.size()) {//没有这门课 29 System.out.println(temp[2] + " does not exist"); 30 flag = 1; 31 } 32 if (courses.size() > 0) { 33 int m = 0; 34 if (flag == 0) {//有课的情况 35 if (courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 36 if(courses.get(n).getCourseNature().equals("选修")){ 37 double x = Double.parseDouble(temp[3]);//选修的成绩 38 courses.get(n).getScore().getScores().add(x); 39 // courses.get(n).setScore3(x); 40 courses.get(n).getSumScore(); 41 classes.get(i).getStudents().get(j).setScore3(x); 42 43 } 44 } else { 45 System.out.println(temp[0] + " " + 46 temp[1] + " : " + "access mode mismatch"); 47 } 48 } 49 } 50 } 51 if(temp.length == 5){//选修 或 必修的考试 52 int flag = 0; 53 for (n = 0; n < courses.size(); n++) {//有这门课 54 if (courses.get(n).getName().equals(temp[2])) { 55 break; 56 } 57 } 58 if (n == courses.size()) {//没有这门课 59 System.out.println(temp[2] + " does not exist"); 60 flag = 1; 61 } 62 if (courses.size() > 0) { 63 int m = 0; 64 if (flag == 0) {//有课的情况 65 if (!courses.get(n).getInvestigationMethod().equals("考察")) {//这节课的是考察 66 double x = Double.parseDouble(temp[3]); 67 double y = Double.parseDouble(temp[4]); 68 // 69 courses.get(n).getScore().getScores().add(x); 70 courses.get(n).getScore().getScores().add(y); 71 // 72 courses.get(n).getSumScore(); 73 classes.get(i).getStudents().get(j).setScore3(courses.get(n).getScore().getSum()); 74 courses.get(n).getScore().getScores().clear(); 75 } else { 76 System.out.println(temp[0] + " " + 77 temp[1] + " : " + "access mode mismatch"); 78 } 79 } 80 } 81 82 } 83 }
这里代码有重复的部分,可以先进行查找班级和学生的操作,在分别对考试和考察的情况进行分析。这样就可以简化代码,程序更易于阅读。
5.总结
1.通过这一阶段的学习,我重点掌握了正则表达式的使用,通过运用正则表达式,可以快速地对所需的字符串进行判定。从而达到区分各种情况的目的。
2.Comparable的使用,在期中考试的时候,考到了Comparable接口,用于排序。在Conllection的子类中,都可以有sort方法,而只需让需要排序的类重写Comparable接口里的CompareTo()方法,就可以了。这个排序方法用的比较多,用起来也十分方便。
3.HashMap的使用,HashMap作为一种特殊的容器,存放的都是一个个键值对,但是键不能重复,值可以重复。HahMap的索引是通过键来找到值的,map.get()的方法十分简便。必要时,也可以获得HashMap里值的集合。例如: List<Map.Entry<String,Student>> list = new ArrayList<>(map.entrySet());来获得一个列表,该列表的元素全是Student的对象。
4.equals的覆盖.
这里的obj需要向下转型,才能使用PersonOverride里的isGender()和getAge()方法,不然无法实现equals()的覆盖。
5.建议:在每次写完PTA的题目,可以发一份参考的代码,或者时让获得满分的同学分享一下解题思路,并且可以展示他们的代码写的优秀的地方。促进大家的交流合作,以获得更好的进步。
二.评价
1.教学方法(边讲边练):有些没太听懂的地方,练起来就无从下手。所以希望讲的时候能讲的更清楚一些,让同学们理解。
2.教学组织(线上线下教学):学习通的网课开通时间太短了,每次想看的时候都发现第一节已经关课了,就会有一些课看不到。希望时间可以更长。
3.教学过程(PTA题目驱动):写PTA当然是好的,但是每次写完PTA之后,都不知道自己还有哪些可以改进的地方(尤其是对于还没有满分的同学),希望就是每次写完一次作业集都可以发一下参考答案(参考的代码)。让同学们看看哪些地方需要改进。