BLOG-3
这次的pta6-8:Java实现课程成绩统计程序的系列作业是一项非常有意义和实用的任务。通过编写这个程序,我们可以更好地理解和应用Java编程语言的知识,同时也能够提高我们的编程能力和解决问题的能力。 首先,这个程序的主要功能是统计和分析学生的课程成绩。通过输入学生的姓名和成绩,程序可以计算出每个学生的总分、平均分、最高分和最低分,并且可以按照总分进行排序。这样,老师和学生可以更方便地了解每个学生的学习情况,对学生的学习成绩进行评估和分析。 其次,这个程序的实现过程中,我们需要运用到Java编程语言的一些基本知识和技巧。比如,我们需要使用数组来存储学生的姓名和成绩,使用循环结构来遍历数组并进行计算,使用条件语句来判断和处理异常情况等等。通过实际编写代码,我们可以更深入地理解和掌握这些知识和技巧,提高我们的编程能力。 此外,这个程序还可以进行一些扩展和优化。比如,我们可以添加一个功能,让用户可以输入学生的学号和其他相关信息,以便更全面地了解学生的学习情况。我们还可以对程序进行性能优化,比如使用更高效的算法来进行排序,提高程序的执行效率。 总的来说,这次的Java实现课程成绩统计程序的作业是一项非常有意义和实用的任务。通过编写这个程序,我们不仅可以提高我们的编程能力和解决问题的能力,还可以更好地了解和应用Java编程语言的知识。相信通过这样的实践和学习,我们可以在未来的编程工作中取得更好的成果。
除了课程成绩统计程序之外,本篇博客还将对动物发声模拟器(多态)、 jmu-Java-03面向对象基础-05-覆盖题目设计分析。
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
这个题目涉及到的知识点主要包括Java的输入输出、字符串处理、条件判断、循环、数组、排序等。
首先,需要使用Java的输入输出方法来读取题目给出的输入信息,包括课程信息和课程成绩信息。可以使用Scanner类来读取输入信息,并使用System.out.println()方法来输出结果。
其次,需要对输入的信息进行解析和处理。可以使用字符串的split()方法将输入的字符串按照空格进行分割,得到各个字段的值。然后,根据题目要求进行相应的判断和计算。例如,判断课程性质和考核方式是否匹配,判断成绩是否在合法范围内,计算各个平均分等。
接下来,需要使用条件判断和循环来处理异常情况和计算平均分。根据题目要求,需要判断课程名称是否存在、成绩数量和考核方式是否匹配等异常情况,并输出相应的错误信息。同时,需要使用循环来计算学生课程总成绩平均分、单门课程成绩平均分和班级所有课程总成绩平均分。
最后,需要使用数组和排序来对学生课程总成绩平均分和班级所有课程总成绩平均分进行排序。可以使用数组来存储学生的成绩信息,并使用Arrays.sort()方法对数组进行排序。然后,按照题目要求输出排序后的结果。
总体来说,这个题目的难度适中,需要对输入信息进行解析和处理,并进行相应的计算和判断。同时,还需要使用一些Java的基本知识和方法来完成题目要求。
源码如下:
1 import java.text.Collator; 2 import java.util.ArrayList; 3 import java.util.Comparator; 4 import java.util.Scanner; 5 6 public class Main { 7 public static void main(String[] args) { 8 Schedule schedule = new Schedule(); 9 Scanner input = new Scanner(System.in); 10 Grade grade = new Grade(); 11 12 while (true) { 13 String str1 = input.nextLine(); 14 if (str1.equals("end")) { 15 break; 16 } 17 String[] token = str1.split(" "); 18 if (token.length == 3 && isValidCourse(token)) { 19 if (schedule.searchCourseByName(token[0]) == -1) { 20 schedule.addACourse(token[0], token[1], token[2]); 21 } 22 } else if (token.length >= 4 && isValidStudent(token)) { 23 String classNum = token[0].substring(0, 6); 24 int classNumInGrade = grade.searchClassByNum(classNum); 25 if (classNumInGrade == -1) { 26 grade.addAClass(classNum); 27 grade.classes.get(grade.classes.size() - 1).addAStudent(token, schedule); 28 } else { 29 int studentNumInClass = grade.classes.get(classNumInGrade).searchStudentByID(token[0]); 30 if (studentNumInClass == -1) { 31 grade.classes.get(classNumInGrade).addAStudent(token, schedule); 32 } else { 33 grade.classes.get(classNumInGrade).addACourseToStudent(studentNumInClass, token, schedule); 34 } 35 } 36 } else { 37 System.out.println("wrong format"); 38 } 39 } 40 41 grade.showStudentScores(); 42 grade.getSumUp(); 43 schedule.getEndScores(); 44 schedule.showEndScores(); 45 grade.showClassScores(); 46 } 47 48 private static boolean isValidCourse(String[] token) { 49 return token[1].equals("必修") || token[1].equals("选修") && token[2].equals("考试") || token[2].equals("考察"); 50 } 51 52 private static boolean isValidStudent(String[] token) { 53 return token[0].matches("[\\d]{8}") && token[3].matches("[0-9]{1,4}"); 54 } 55 } 56 57 class Course { 58 public String name; 59 public String type; 60 public String assessMode; 61 public int midScore; 62 public double midScorePercent = 0.3; 63 public int finalScore; 64 public double finalScorePercent = 0.7; 65 public int endScore; 66 public int gradeNum = 0; 67 68 public Course(String name, String quality, String assessMode) { 69 this.name = name; 70 this.type = quality; 71 this.assessMode = assessMode; 72 } 73 74 public String getName() { 75 return name; 76 } 77 78 public void getEndScore() { 79 if (gradeNum == 0) return; 80 midScore = (int) Math.floor(midScore / gradeNum); 81 finalScore = (int) Math.floor(finalScore / gradeNum); 82 endScore = assessMode.equals("考察") ? finalScore : (int) Math.floor(midScore * midScorePercent + finalScore * finalScorePercent); 83 } 84 85 public void showEndScore() { 86 if (endScore == 0) { 87 System.out.println(name + " has no grades yet"); 88 } else { 89 System.out.println(name + " " + (assessMode.equals("考察") ? finalScore : midScore + " " + finalScore) + " " + endScore); 90 } 91 } 92 } 93 94 class Schedule { 95 public ArrayList<Course> courses = new ArrayList<>(); 96 97 public void addACourse(String name, String quality, String assessMode) { 98 if (quality.equals("必修") && assessMode.equals("考察")) { 99 System.out.println(name + " : course type & access mode mismatch"); 100 return; 101 } 102 courses.add(new Course(name, quality, assessMode)); 103 } 104 105 public int searchCourseByName(String name) { 106 for (int i = 0; i < courses.size(); i++) { 107 if (courses.get(i).getName().equals(name)) { 108 return i; 109 } 110 } 111 return -1; 112 } 113 114 public void getEndScores() { 115 for (Course course : courses) { 116 course.getEndScore(); 117 } 118 } 119 120 public void showEndScores() { 121 courses.sort(Comparator.comparing(Course::getName, Collator.getInstance(java.util.Locale.CHINA))); 122 for (Course course : courses) { 123 course.showEndScore(); 124 } 125 } 126 } 127 128 129 class Student { 130 String studentID; 131 String name; 132 int midScore; 133 int finalScore; 134 int endScore; 135 Course learnedCourse; 136 ArrayList<String> hasLearnedCourse = new ArrayList<>(); 137 int hasLearned = 0; 138 139 public void getSum() { 140 if (learnedCourse == null) { 141 endScore = 0; 142 return; 143 } 144 if (learnedCourse.assessMode.equals("考察")) { 145 endScore += finalScore; 146 } else { 147 endScore += (int) Math.floor(midScore * learnedCourse.midScorePercent + finalScore * learnedCourse.finalScorePercent); 148 } 149 midScore = 0; 150 finalScore = 0; 151 learnedCourse = null; 152 } 153 154 public void showScore() { 155 if (hasLearned != 0) { 156 endScore /= hasLearned; 157 } 158 if (endScore == 0) { 159 System.out.println(studentID + " " + name + " " + "did not take any exams"); 160 } else { 161 System.out.println(studentID + " " + name + " " + endScore); 162 } 163 } 164 165 public void addACourse(String[] token, Schedule schedule) { 166 if (schedule.searchCourseByName(token[2]) == -1) { 167 System.out.println(token[2] + " does not exist"); 168 return; 169 } 170 Course nowCourse = schedule.courses.get(schedule.searchCourseByName(token[2])); 171 learnedCourse = nowCourse; 172 if ((nowCourse.assessMode.equals("考察") && token.length > 4) || (nowCourse.assessMode.equals("考试") && token.length < 5)) { 173 System.out.println(studentID + " " + name + " " + ": access mode mismatch"); 174 return; 175 } 176 if (learnedCourse.assessMode.equals("考察")) { 177 if (Integer.parseInt(token[3]) > 100) { 178 System.out.println("wrong format"); 179 return; 180 } 181 finalScore = Integer.parseInt(token[3]); 182 nowCourse.finalScore += Integer.parseInt(token[3]); 183 } else { 184 if (Integer.parseInt(token[3]) > 100 || Integer.parseInt(token[4]) > 100) { 185 System.out.println("wrong format"); 186 return; 187 } 188 midScore = Integer.parseInt(token[3]); 189 nowCourse.midScore += Integer.parseInt(token[3]); 190 finalScore = Integer.parseInt(token[4]); 191 nowCourse.finalScore += Integer.parseInt(token[4]); 192 } 193 nowCourse.gradeNum++; 194 hasLearned++; 195 hasLearnedCourse.add(token[2]); 196 getSum(); 197 } 198 199 boolean ifHasLearned(String course) { 200 return hasLearnedCourse.contains(course); 201 } 202 } 203 204 class Class { 205 String classNum; 206 ArrayList<Student> students = new ArrayList<>(); 207 int stuNum = 0; 208 int AverageScore; 209 210 public void addAStudent(String[] token, Schedule schedule) { 211 Student temp = new Student(); 212 temp.studentID = token[0]; 213 temp.name = token[1]; 214 temp.addACourse(token, schedule); 215 students.add(temp); 216 } 217 218 public int searchStudentByID(String studentID) { 219 for (int i = 0; i < students.size(); i++) { 220 if (students.get(i).studentID.equals(studentID)) { 221 return i; 222 } 223 } 224 return -1; 225 } 226 227 public void addACourseToStudent(int i, String[] token, Schedule schedule) { 228 Student temp = students.get(i); 229 if (temp.ifHasLearned(token[2])) { 230 return; 231 } 232 temp.addACourse(token, schedule); 233 } 234 235 public void getSumUp() { 236 for (Student student : students) { 237 AverageScore += student.endScore; 238 if (student.endScore != 0) stuNum++; 239 } 240 if (stuNum != 0) { 241 AverageScore /= stuNum; 242 } 243 } 244 245 public void showStudentScore() { 246 students.sort(Comparator.comparing(o -> o.studentID)); 247 for (Student student : students) { 248 student.showScore(); 249 } 250 } 251 252 public void showClassScore() { 253 if (AverageScore == 0) { 254 System.out.println(classNum + " has no grades yet"); 255 } else { 256 System.out.println(classNum + " " + AverageScore); 257 } 258 } 259 } 260 261 class Grade { 262 ArrayList<Class> classes = new ArrayList<>(); 263 264 public int searchClassByNum(String classNum) { 265 for (int i = 0; i < classes.size(); i++) { 266 if (classes.get(i).classNum.equals(classNum)) { 267 return i; 268 } 269 } 270 return -1; 271 } 272 273 public void addAClass(String classNum) { 274 Class temp = new Class(); 275 temp.classNum = classNum; 276 classes.add(temp); 277 } 278 279 public void getSumUp() { 280 for (Class aClass : classes) { 281 aClass.getSumUp(); 282 } 283 } 284 285 public void showStudentScores() { 286 classes.sort(Comparator.comparing(o -> o.classNum)); 287 for (Class aClass : classes) { 288 aClass.showStudentScore(); 289 } 290 } 291 292 public void showClassScores() { 293 classes.sort(Comparator.comparing(o -> o.classNum)); 294 for (Class aClass : classes) { 295 aClass.showClassScore(); 296 } 297 } 298 }
类图:
课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩的平均分
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
这道题目涉及到的知识点主要包括字符串处理、条件判断、循环、数组、排序等。其中,字符串处理主要用于解析输入的信息,包括课程信息和成绩信息;条件判断用于判断输入的信息是否符合要求,如成绩是否在范围内、课程性质和考核方式是否匹配等;循环用于遍历成绩信息和课程信息,计算总成绩和平均分;数组用于存储成绩和课程信息;排序用于按学号和班级号进行排序。
难点和易错点主要包括以下几个方面:
1. 输入信息的解析:需要正确解析输入的字符串,提取出学号、姓名、课程名称、成绩等信息,并进行相应的类型转换。
2. 条件判断和错误处理:需要根据题目要求进行条件判断,如判断成绩是否在范围内、课程性质和考核方式是否匹配等。同时,还需要处理各种异常情况,如格式错误、重复的课程/成绩信息等。
3. 平均分的计算:需要正确计算各种平均分,包括学生课程总成绩平均分、单门课程成绩平均分、班级所有课程总成绩平均分。在计算平均分时,需要注意取整数部分,丢弃小数部分。
代码可以改进的地方包括:
1. 使用合适的数据结构:可以使用HashMap来存储课程信息和成绩信息,以便快速查找和更新。
2. 优化算法:在计算平均分时,可以使用累加的方式,避免重复遍历成绩信息和课程信息。
3. 代码重用:可以将一些重复的代码封装成函数或方法,提高代码的可读性和可维护性。 总之,这道题目需要对输入信息进行解析和处理,根据题目要求进行条件判断和错误处理,最后计算各种平均分并按要求输出。在实现代码时,需要注意处理各种异常情况,并尽可能优化算法和代码结构。
源码如下:
1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.HashMap; 5 import java.util.HashSet; 6 import java.util.List; 7 import java.util.Scanner; 8 9 10 public class Main { 11 public static void main(String[] args) 12 { 13 Scanner in=new Scanner(System.in); 14 int d=0; 15 int g=0; 16 HashMap<String,Course> allcourse=new HashMap<String,Course>();//总课程,String存课程名称 17 HashMap<String,Student> allstudent=new HashMap<String,Student>();//总学生,String存学号 18 HashSet<Control> selection=new HashSet<Control>();//总选课系统 19 HashMap<String,Class> allclass=new HashMap<String,Class>();//总班级,String存班号 20 while(true) 21 { 22 String a=in.nextLine(); 23 if(a.equals("end"))//结束 24 break; 25 String[] b=a.split(" "); 26 //输入课程信息 27 if(a.matches("(\\S{1,10})( )(必修|选修|实验)(( )(考试|考察|实验))?")) 28 { 29 if (b.length == 2) { 30 if (b[1].equals("选修") || b[1].equals("实验")) { 31 System.out.println(b[0] + " : 课程类型与考核方式不匹配"); 32 } else if (allcourse.containsKey(b[0])) { 33 // 重复输入忽略本条 34 continue; 35 } else if (b[1].equals("必修")) { 36 // 正常输入必修课 37 Course course = new RequiredCourse(b[0]); 38 allcourse.put(b[0], course); 39 } else if (b[1].equals("实验")) { 40 // 正常输入实验课 41 Course course = new Experimentallesson(b[0]); 42 allcourse.put(b[0], course); 43 } 44 } else if (b.length == 3) { 45 if ((b[1].equals("必修") && !b[2].equals("考试")) 46 || (b[1].equals("实验") && !b[2].equals("实验")) 47 || (b[1].equals("选修") && b[2].equals("实验"))) { 48 System.out.println(b[0] + " : course type & access mode mismatch"); 49 } else if (allcourse.containsKey(b[0])) { 50 // 重复输入课程 51 continue; 52 } else if (b[1].equals("必修")) { 53 // 正常输入必修课 54 Course course = new RequiredCourse(b[0]); 55 allcourse.put(b[0], course); 56 } else if (b[1].equals("选修")) { 57 // 正常输入选修课 58 Course course = new OptionalCourse(b[0], b[2]); 59 allcourse.put(b[0], course); 60 } else if (b[1].equals("实验")) { 61 // 正常输入实验课 62 Course course = new Experimentallesson(b[0]); 63 allcourse.put(b[0], course); 64 } 65 } 66 } 67 //输入考试/考察成绩信息 68 else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )(\\d{1,2}|(100))(( )(\\d{1,2}|(100)))?")) 69 { 70 if (!allcourse.containsKey(b[2])) { 71 System.out.println(b[2] + " does not exist"); 72 if (!allstudent.containsKey(b[0])) { 73 Student student = new Student(b[1], b[0]); 74 allstudent.put(b[0], student); 75 String classId = b[0].substring(0, 6); 76 if (!allclass.containsKey(classId)) { 77 Class cla = new Class(); 78 cla.addnum(classId); 79 allclass.put(classId, cla); 80 } 81 allclass.get(classId).addstu(student); 82 } 83 } 84 if (b.length == 4 && allcourse.get(b[2]).getAssess().equals("考试") || b.length == 5 && allcourse.get(b[2]).getAssess().equals("考察")) { 85 System.out.println(b[0] + " " + b[1] + " : access mode mismatch"); 86 if (allstudent.get(b[0]) == null) { 87 Student student = new Student(b[1], b[0]); 88 allstudent.put(b[0], student); 89 String classId = b[0].substring(0, 6); 90 if (allclass.get(classId) == null) { 91 Class cla = new Class(); 92 cla.addnum(classId); 93 allclass.put(classId, cla); 94 } 95 allclass.get(classId).addstu(student); 96 } 97 } 98 else if (judge(selection, allstudent.get(b[0]), allcourse.get(b[2]))) { // 重复的成绩信息 99 continue; 100 } else if (allcourse.get(b[2]).getAssess().equals("考试")) { // 输入考试课成绩信息 101 Achievement achievement = new Text(Integer.parseInt(b[3]), Integer.parseInt(b[4])); 102 Student student = allstudent.getOrDefault(b[0], new Student(b[1], b[0])); 103 allstudent.put(b[0], student); 104 Class cla = allclass.getOrDefault(b[0].substring(0, 6), new Class()); 105 cla.addnum(b[0].substring(0, 6)); 106 cla.addstu(student); 107 allclass.put(b[0].substring(0, 6), cla); 108 Control control = new Control(); 109 control.setMessage(student, allcourse.get(b[2]), achievement); 110 selection.add(control); 111 } 112 113 else//输入考察课成绩信息 114 { 115 116 Achievement achievement = new Examine(Integer.parseInt(b[3])); 117 Control control = new Control(); 118 119 // 判断学生是否已经存在 120 if (!allstudent.containsKey(b[0])) { 121 // 学生不存在,创建新的学生对象并添加到allstudent中 122 Student student = new Student(b[1], b[0]); 123 allstudent.put(b[0], student); 124 125 // 判断班级是否已经存在 126 String classId = b[0].substring(0, 6); 127 if (!allclass.containsKey(classId)) { 128 // 班级不存在,创建新的班级对象并添加到allclass中 129 Class cla = new Class(); 130 cla.addnum(classId); 131 allclass.put(classId, cla); 132 } 133 134 // 将学生添加到班级中 135 allclass.get(classId).addstu(student); 136 } 137 138 // 将成绩信息添加到Control对象中 139 control.setMessage(allstudent.get(b[0]), allcourse.get(b[2]), achievement); 140 141 // 将Control对象添加到selection中 142 selection.add(control); 143 } 144 } 145 //输入实验成绩 146 else if(a.matches("(\\d{8})( )(\\S{1,10})( )(\\S{1,10})( )([4-9])( )((\\d{1,2}|(100))( ))*(\\d{1,2}|(100)*)")) 147 { 148 if(!allcourse.containsKey(b[2])) {//课程名称不在已输入的课程列表中 149 System.out.println(b[2] + " does not exist"); 150 if(!allstudent.containsKey(b[0])) { 151 Student student = new Student(b[1], b[0]); 152 allstudent.put(b[0], student); 153 String classId = b[0].substring(0, 6); 154 if(!allclass.containsKey(classId)) { 155 Class cla = new Class(); 156 cla.addnum(classId); 157 allclass.put(classId, cla); 158 } 159 allclass.get(classId).addstu(student); 160 } 161 } 162 else if (b.length - 4 != Integer.parseInt(b[3])) { 163 System.out.println(b[0] + " " + b[1] + " : access mode mismatch"); 164 Student student = allstudent.getOrDefault(b[0], new Student(b[1], b[0])); 165 allstudent.put(b[0], student); 166 Class cla = allclass.getOrDefault(b[0].substring(0, 6), new Class()); 167 cla.addnum(b[0].substring(0, 6)); 168 cla.addstu(student); 169 allclass.put(b[0].substring(0, 6), cla); 170 } 171 else if(judge(selection,allstudent.get(b[0]),allcourse.get(b[2]))); 172 else//输入实验成绩信息 173 { 174 int[] e = new int[b.length - 4]; 175 for (int i = 0; i < e.length; i++) { 176 e[i] = Integer.parseInt(b[i + 4]); 177 } 178 Achievement achievement = new Experimental(e.length, e); 179 Control control = new Control(); 180 String studentId = b[0]; 181 if (!allstudent.containsKey(studentId)) { 182 Student student = new Student(b[1], studentId); 183 allstudent.put(studentId, student); 184 String classId = studentId.substring(0, 6); 185 if (!allclass.containsKey(classId)) { 186 Class cla = new Class(); 187 cla.addnum(classId); 188 allclass.put(classId, cla); 189 } 190 allclass.get(classId).addstu(student); 191 } 192 control.setMessage(allstudent.get(studentId), allcourse.get(b[2]), achievement); 193 selection.add(control); 194 } 195 } 196 else 197 System.out.println("wrong format"); 198 } 199 List<Student> mapValues = new ArrayList<>(allstudent.values()); 200 Collections.sort(mapValues); 201 for (Student i : mapValues) { 202 int totalScore = 0; 203 int examCount = 0; 204 for (Control control : selection) { 205 if (i.equals(control.getStudent())) { 206 totalScore += control.getTotalScore(); 207 examCount++; 208 } 209 } 210 if (examCount == 0) { 211 System.out.println(i.getNumber() + " " + i.getName() + " did not take any exams"); 212 } else { 213 int averageScore = totalScore / examCount; 214 System.out.println(i.getNumber() + " " + i.getName() + " " + averageScore); 215 } 216 } 217 List<Course> courseValues = new ArrayList<>(allcourse.values()); 218 Collections.sort(courseValues,new SortName()); 219 for(Course i:courseValues) 220 { 221 int u=0;//平时 222 int f=0;//期末 223 int s=0;//总 224 int n=0; 225 for(Control j:selection) 226 if(i==j.getCourse()) 227 {if ("考试".equals(i.getAssess())) { 228 u += j.getScore().getUsualPerformance(); 229 f += j.getScore().getFinalGrade(); 230 } else if ("考察".equals(i.getAssess())) { 231 f += j.getScore().getFinalGrade(); 232 } 233 s += j.getScore().getTotalScore(); 234 n++; 235 } 236 if(n==0) 237 System.out.println(i.getName()+" has no grades yet"); 238 else 239 { 240 System.out.print(i.getName()); 241 s /= n; 242 String assess = i.getAssess(); 243 if (assess.equals("考试")) { 244 u /= n; 245 f /= n; 246 System.out.println(" " + u + " " + f + " " + s); 247 } else if (assess.equals("考察")) { 248 f /= n; 249 System.out.println(" " + f + " " + s); 250 } else { 251 System.out.println(" " + s); 252 } 253 } 254 } 255 // for(Class i:allclass.values()) 256 // i.gettotalscore(selection); 257 List<Class> classValues = new ArrayList<>(allclass.values()); 258 Collections.sort(classValues); 259 for (Class i : classValues) { 260 String message = i.hasGrades(selection) ? i.getNum() + " " + i.getTotalScore(selection) : i.getNum() + " has no grades yet"; 261 System.out.println(message); 262 } 263 } 264 public static boolean judge(HashSet<Control> o,Student s,Course c) 265 { 266 return o.stream().anyMatch(i -> i.getStudent() == s && i.getCourse() == c); 267 } 268 } 269 270 //每门课程 271 abstract class Course { 272 private String name; 273 private String assess; 274 275 public Course() { 276 this.name = name; 277 this.assess = assess; 278 } 279 280 public String getName() { 281 return name; 282 } 283 284 public void setName(String name) { 285 this.name = name; 286 } 287 288 public String getAssess() { 289 return assess; 290 } 291 292 public void setAssess(String assess) { 293 this.assess = assess; 294 } 295 } 296 //必修课 297 class RequiredCourse extends Course 298 { 299 RequiredCourse(String name) 300 { 301 super(); 302 setName(name); 303 setAssess("考试"); 304 } 305 306 } 307 //选修课 308 class OptionalCourse extends Course 309 { 310 OptionalCourse(String name,String b) 311 { 312 setName(name); 313 setAssess(b); 314 } 315 } 316 //实验课 317 class Experimentallesson extends Course 318 { 319 Experimentallesson(String name) 320 { 321 setName(name); 322 setAssess("实验"); 323 } 324 } 325 //学生 326 327 class Student implements Comparable<Student> { 328 private final String name; 329 private final String number; 330 331 public Student(String name, String number) { 332 this.name = name; 333 this.number = number; 334 } 335 336 public String getName() { 337 return name; 338 } 339 340 public String getNumber() { 341 return number; 342 } 343 344 @Override 345 public int compareTo(Student o) { 346 return this.number.compareTo(o.getNumber()); 347 } 348 } 349 //选课中心 350 351 class Control { 352 private Student student; 353 private Course course; 354 private Achievement score; 355 356 public Control() { 357 this.student = student; 358 this.course = course; 359 this.score = score; 360 } 361 362 public int getTotalScore() { 363 return score.getTotalScore(); 364 } 365 366 public Student getStudent() { 367 return student; 368 } 369 370 public Course getCourse() { 371 return course; 372 } 373 374 public Achievement getScore() { 375 return score; 376 } 377 378 public void setMessage(Student student, Course course, Achievement score) { 379 this.student = student; 380 this.course = course; 381 this.score = score; 382 } 383 } 384 //成绩 385 386 387 abstract class Achievement { 388 private int finalGrade; // 期末成绩 389 private int usualPerformance; // 平时成绩 390 391 public Achievement() { 392 this.finalGrade = finalGrade; 393 this.usualPerformance = usualPerformance; 394 } 395 396 public void setFinalGrade(int finalGrade) { 397 this.finalGrade = finalGrade; 398 } 399 400 public void setUsualPerformance(int usualPerformance) { 401 this.usualPerformance = usualPerformance; 402 } 403 404 public int getFinalGrade() { 405 return finalGrade; 406 } 407 408 public int getUsualPerformance() { 409 return usualPerformance; 410 } 411 412 public abstract int getTotalScore(); // 计算总成绩 413 } 414 415 // 考试成绩 416 class Text extends Achievement { 417 public Text(int usual, int fina) { 418 super(); 419 } 420 421 @Override 422 public int getTotalScore() { 423 return (int) (getUsualPerformance() * 0.3 + getFinalGrade() * 0.7); 424 } 425 } 426 427 // 考察成绩 428 class Examine extends Achievement { 429 public Examine(int finalGrade) { 430 super(); 431 } 432 433 @Override 434 public int getTotalScore() { 435 return getFinalGrade(); 436 } 437 } 438 439 class Experimental extends Achievement { 440 private int time;//实验次数 441 private List<Integer> scores;//每次实验成绩 442 443 public Experimental(int time, int[] score) { 444 super(); 445 this.time = time; 446 this.scores = new ArrayList<>(); 447 for (int s : score) { 448 scores.add(s); 449 } 450 } 451 452 @Override 453 public int getTotalScore() { 454 int totalScore = 0; 455 for (int s : scores) { 456 totalScore += s; 457 } 458 return totalScore / time; 459 } 460 } 461 //班 462 463 class Class implements Comparable<Class> 464 { 465 private String num;//班级序号 466 private HashSet<Student> students=new HashSet<Student>();//学生 467 void addnum(String num) 468 { 469 this.num=num; 470 } 471 String getNum() 472 { 473 return num; 474 } 475 void addstu(Student student) 476 { 477 students.add(student); 478 } 479 boolean hasGrades(HashSet<Control> o)//判断该班是否有成绩 480 { 481 int n=0; 482 for(Student a:this.students) 483 for(Control b:o) 484 { 485 if(b.getStudent()==a) 486 n++; 487 } 488 if(n==0) 489 return false; 490 return true; 491 } 492 public int getTotalScore(HashSet<Control> controls) { 493 int totalScore = 0; 494 int studentCount = 0; 495 int controlCount = 0; 496 for (Student student : this.students) { 497 int studentTotalScore = 0; 498 int studentControlCount = 0; 499 for (Control control : controls) { 500 if (control.getStudent() == student) { 501 studentTotalScore += control.getTotalScore(); 502 studentControlCount++; 503 } 504 } 505 if (studentControlCount > 0) { 506 totalScore += studentTotalScore / studentControlCount; 507 studentCount++; 508 } 509 controlCount += studentControlCount; 510 } 511 if (studentCount > 0) { 512 return totalScore / studentCount; 513 } else { 514 return 0; 515 } 516 } 517 518 @Override 519 public int compareTo(Class otherClass) { 520 return this.num.compareTo(otherClass.getNum()); 521 } 522 } 523 class SortName implements Comparator<Course> 524 { 525 @Override 526 public int compare(Course o, Course o1) { 527 return o.getName().compareTo(o1.getName()); 528 } 529 }
类图:
课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,
要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。
完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。
题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。
某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。
这个题目涉及的知识点主要包括Java的输入输出、字符串处理、条件判断、循环、数组、排序等基础知识。难点在于解析输入的字符串信息,根据题目要求进行相应的计算和处理,并输出符合要求的结果。 首先,需要解析输入的课程信息和成绩信息。可以使用字符串的split方法将输入的字符串按照空格进行分割,得到相应的课程名称、课程性质、考核方式、权重等信息。然后,根据不同的考核方式进行相应的计算和处理。对于考试课,需要解析学号、姓名、平时成绩和期末成绩等信息;对于考察课,只需要解析学号、姓名和期末成绩;对于实验课,需要解析学号、姓名和每次实验成绩等信息。 在计算总成绩时,需要根据权重值进行相应的计算。对于考试课和考察课,直接将期末成绩作为总成绩;对于实验课,需要将每次实验成绩乘以相应的权重后累加得到总成绩。 在输出结果时,需要按照题目要求进行排序和格式化输出。可以使用数组或集合来存储学生和课程的成绩信息,然后进行排序和输出。同时,需要注意处理异常情况,如课程名称不匹配、成绩数量不匹配、权重值错误等,按照题目要求输出相应的错误信息。 代码可以改进的地方包括使用合适的数据结构来存储成绩信息,提高代码的可读性和可维护性;使用正则表达式来匹配和解析输入的字符串,简化代码逻辑;使用自定义的类来表示课程和成绩信息,提高代码的可扩展性和复用性。 总之,这个题目需要对输入的字符串进行解析和处理,根据题目要求进行相应的计算和输出。需要注意处理异常情况,并对代码进行适当的优化和改进。
源码如下:
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.ArrayList; 4 public class Main { 5 public static void main(String[] args) { 6 Scanner s = new Scanner(System.in); 7 String s_record = s.nextLine(); 8 ParseInput handle=new ParseInput(); 9 while (!s_record.equals("end")) { 10 handle.parseInput(s_record);//解析用户输入的每一行数据 11 s_record = s.nextLine(); 12 } 13 handle.showStudents(); 14 handle.showCourses(); 15 handle.showClasses(); 16 } 17 } 18 class ParseInput{ 19 ArrayList<Student> listStudent=new ArrayList<>(); 20 ArrayList<Course> listCourse=new ArrayList<>(); 21 ArrayList<Class> listClass=new ArrayList<>(); 22 ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>(); 23 24 public void parseInput(String str){ 25 InputMatching mat=new InputMatching(); 26 int flag=mat.matchingInput(str); 27 switch (flag){ 28 case 0:System.out.println("wrongformat"); 29 break; 30 //课程信息 31 case 1:courseMessage(str); 32 break; 33 //成绩信息 34 case 2:gradeMessage(str); 35 break; 36 } 37 } 38 public void courseMessage(String str) { 39 String[] letters = str.split(" "); 40 String courseName = letters[0]; 41 String type = letters[1]; 42 String testType = letters[2]; 43 float totalPower = 0; 44 int num = Integer.parseInt(letters[3]); 45 if ((letters.length - 4) != num) { 46 System.out.println(courseName + " : number of scores does not match"); 47 } else { 48 for (int i = 4; i < letters.length; i++) { 49 totalPower += Float.parseFloat(letters[i]); 50 } 51 if (totalPower != 1.0) { 52 System.out.println(courseName + " : weight value error"); 53 } else { 54 ArrayList<String> power = new ArrayList<>(); 55 for (int i = 4; i < letters.length; i++) { 56 power.add(letters[i]); 57 } 58 Course course = new Course(courseName, type, testType, power); 59 if (checkCourse(course) && searchCourse(courseName) == null) { 60 listCourse.add(course); 61 } 62 } 63 } 64 } 65 public void gradeMessage(String str){ 66 String letters[]=str.split(" "); 67 68 String stuId= letters[0];//学生学号 69 String classID= letters[0].substring(0,6); 70 String name=letters[1];//学生姓名 71 String courseName=letters[2];//课程名字 72 73 //如果该班级第一次出现 74 if(searchClass(classID)==null){ 75 Class cla=new Class(classID); 76 listClass.add(cla); 77 } 78 79 Student stu=new Student(classID,stuId,name); 80 81 if(!searchStudent(stuId)) 82 listStudent.add(stu);//将学生加入列表中 83 84 //课程是否存在 85 if(searchCourse(courseName)==null){ 86 System.out.println(courseName+" "+"does not exist"); 87 } 88 89 //当课程存在时 90 else if(searchCourse(courseName)!=null){ 91 Course course=searchCourse(courseName); 92 //考察 93 if(letters.length==4&&course.testType.equals("考察")){ 94 int finalGrade= Integer.parseInt(letters[3]); 95 AssessGrade assessGrade=new AssessGrade(finalGrade); 96 ChooseCourse chooseCourse=new ChooseCourse(course,stu,assessGrade); 97 if(!searchChooseCourse(name,courseName)) 98 listChooseCourse.add(chooseCourse); 99 } 100 //考试 101 else if(letters.length==5&&course.testType.equals("考试")){ 102 int usualGrade= Integer.parseInt(letters[3]); 103 int finalGrade= Integer.parseInt(letters[4]); 104 ExamGrade examGrade=new ExamGrade(usualGrade,finalGrade,course.powers); 105 ChooseCourse chooseCourse=new ChooseCourse(course,stu,examGrade); 106 listChooseCourse.add(chooseCourse); 107 } 108 else if(letters.length>5&&course.testType.equals("实验")){ 109 int exNum= course.powers.size(); 110 if(exNum!=letters.length-3){ 111 //20201103 张三 : access mode mismatch 112 System.out.println(stuId+" "+name+" "+": access mode mismatch"); 113 return; 114 } 115 ArrayList<Integer> scores = new ArrayList<>(); 116 /**实验课程信息格式:0学号+英文空格+1姓名+英文空格+2课程名称+英文空格+3实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩*/ 117 for(int i=3;i<letters.length;i++){ 118 scores.add(Integer.parseInt(letters[i])); 119 } 120 ExperimentGrade experimentGrade=new ExperimentGrade(scores,course.powers); 121 ChooseCourse chooseCourse=new ChooseCourse(course,stu,experimentGrade); 122 listChooseCourse.add(chooseCourse); 123 } 124 else{ 125 //学号+英文空格+姓名+英文空格+": access mode mismatch" 126 System.out.println(stuId+" "+name+" "+": access mode mismatch"); 127 } 128 } 129 } 130 131 public boolean checkCourse(Course course){ 132 String type = course.getType(); 133 String testType = course.getTestType(); 134 if(type.equals("必修") && testType.equals("考试")){ 135 return true; 136 } 137 if(type.equals("选修") && (testType.equals("考试") || testType.equals("考察"))){ 138 return true; 139 } 140 if(type.equals("实验") && testType.equals("实验")){ 141 return true; 142 } 143 System.out.println(course.getCourseName()+" : course type & access mode mismatch"); 144 return false; 145 } 146 public Class searchClass(String classId){ 147 return listClass.stream() 148 .filter(cls -> cls.getClassId().equals(classId)) 149 .findFirst() 150 .orElse(null); 151 } 152 153 public Course searchCourse(String name){ 154 return listCourse.stream() 155 .filter(course -> course.getCourseName().equals(name)) 156 .findFirst() 157 .orElse(null); 158 } 159 public boolean searchStudent(String id){ 160 return listStudent.stream().anyMatch(stu -> stu.getId().equals(id)); 161 } 162 //查找是否有重复选课成绩 163 public boolean searchChooseCourse(String stuName,String courseName){ 164 return listChooseCourse.stream().anyMatch(cs -> cs.student.getStuName().equals(stuName) && cs.course.getCourseName().equals(courseName)); 165 } 166 public void showStudents(){ 167 listStudent.sort(Comparator.naturalOrder()); 168 for(Student stu : listStudent){ 169 ArrayList<ChooseCourse> stuCourseSelects = getStudentSelects(stu.getId()); 170 if(!stuCourseSelects.isEmpty()) { 171 System.out.println(stu.getId() + " " + stu.getStuName() + " " + getAvgTotalScore(stuCourseSelects)); 172 } 173 else { 174 System.out.println(stu.getId() + " " + stu.getStuName() + " did not take any exams"); 175 } 176 } 177 } 178 //java 选修 考察 179 public void showCourses() { 180 Collections.sort(listCourse); 181 for (Course course : listCourse) { 182 ArrayList<ChooseCourse> stuCourseSelects = getCourseSelects(course.getCourseName()); 183 if (!stuCourseSelects.isEmpty()) { 184 switch (course.getTestType()) { 185 case "考试": 186 case "考察": 187 case "实验": 188 System.out.println(course.getCourseName() + " " + getAvgTotalScore(stuCourseSelects)); 189 break; 190 default: 191 break; 192 } 193 } else { 194 System.out.println(course.getCourseName() + " " + "has no grades yet"); 195 } 196 } 197 } 198 public void showClasses(){ 199 listClass.sort(Comparator.naturalOrder()); 200 for(Class cls : listClass){ 201 ArrayList<ChooseCourse> stuCourseSelects = getClassSelects(cls.getClassId()); 202 if(!stuCourseSelects.isEmpty()){ 203 System.out.println(cls.getClassId() + " " + getAvgTotalScore(stuCourseSelects)); 204 } 205 else{ 206 System.out.println(cls.getClassId() + " " + "has no grades yet"); 207 } 208 } 209 } 210 public ArrayList<ChooseCourse> getStudentSelects(String id){ 211 ArrayList<ChooseCourse> choose=new ArrayList<>(); 212 for(ChooseCourse cos:listChooseCourse) { 213 if (cos.student.getId().equals(id)) 214 choose.add(cos); 215 } 216 return choose; 217 } 218 public ArrayList<ChooseCourse> getCourseSelects(String courseName){ 219 ArrayList<ChooseCourse> choose=new ArrayList<>(); 220 for(ChooseCourse cos:listChooseCourse) { 221 if (cos.course.getCourseName().equals(courseName)) 222 choose.add(cos); 223 } 224 return choose; 225 } 226 public ArrayList<ChooseCourse> getClassSelects(String clsId){ 227 ArrayList<ChooseCourse> choose =new ArrayList<>(); 228 for(ChooseCourse cos:listChooseCourse) { 229 if (cos.student.getClsId().equals(clsId)) 230 choose.add(cos); 231 } 232 return choose; 233 } 234 public int getAvgTotalScore(ArrayList<ChooseCourse> cs){ 235 int sum=0; 236 for(ChooseCourse c:cs){ 237 sum+=c.grade.getTotalGrade(); 238 } 239 return (int)(sum/cs.size()); 240 } 241 242 } 243 class ChooseCourse{ 244 Course course; 245 Student student; 246 Grade grade; 247 248 public ChooseCourse(Course course,Student student,Grade grade) { 249 this.course = course; 250 this.student=student; 251 this.grade=grade; 252 } 253 } 254 class Student implements Comparable<Student> { 255 private String stuName; 256 private String id; 257 private String clsId; 258 259 public String getId() { 260 return id; 261 } 262 263 public String getStuName() { 264 return stuName; 265 } 266 267 public String getClsId() { 268 return clsId; 269 } 270 271 public Student(String clsId, String id, String stuName) { 272 this.clsId = clsId; 273 this.id = id; 274 this.stuName = stuName; 275 } 276 277 @Override 278 public int compareTo(Student stu) { 279 return this.id.compareTo(stu.getId()); 280 } 281 } 282 class Course implements Comparable<Course>{ 283 String courseName; 284 String type; 285 String testType; 286 ArrayList<String> powers =new ArrayList<>(); 287 288 289 public Course(String courseName, String type, String testType, ArrayList<String> powers) { 290 this.courseName = courseName; 291 this.type = type; 292 this.testType = testType; 293 this.powers = powers; 294 } 295 296 public String getCourseName(){ 297 return courseName; 298 } 299 public String getType(){ 300 return type; 301 } 302 public String getTestType(){ 303 return testType; 304 } 305 @Override 306 public int compareTo(Course o) { 307 Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); 308 return compare.compare(courseName,o.getCourseName()); 309 } 310 311 } 312 class Class implements Comparable<Class>{ 313 String classId; 314 315 public Class() { 316 } 317 318 public String getClassId(){ 319 return classId; 320 } 321 public Class(String classId) { 322 this.classId = classId; 323 } 324 @Override 325 public int compareTo(Class o) { 326 return getClassId().compareTo(o.getClassId()); 327 } 328 } 329 abstract class Grade{ 330 int finalGrade; 331 ArrayList<String> powers=new ArrayList<>(); 332 public Grade() { 333 } 334 public abstract int getUsualGrade(); 335 public abstract int getTotalGrade(); 336 } 337 class ExamGrade extends Grade{ 338 int usualGrade; 339 340 float usualPower; 341 float finalPower; 342 ArrayList<Float> powers=new ArrayList<>(); 343 public ExamGrade(int usualGrade,int finalGrade,ArrayList<String> powers) { 344 super.finalGrade=finalGrade; 345 this.usualGrade = usualGrade; 346 super.powers=powers; 347 } 348 349 public int getUsualGrade(){ 350 return usualGrade; 351 } 352 public int getTotalGrade(){ 353 return (int)(usualGrade*powers.get(0)+finalGrade*powers.get(1)); 354 } 355 } 356 class AssessGrade extends Grade{ 357 358 public AssessGrade(int finalGrade) { 359 this.finalGrade=finalGrade; 360 } 361 362 @Override 363 public int getUsualGrade() { 364 return 0; 365 } 366 367 public int getTotalGrade(){ 368 return finalGrade; 369 } 370 } 371 class ExperimentGrade extends Grade{ 372 ArrayList<Integer> exGrade=new ArrayList<>();//成绩 373 public ExperimentGrade(ArrayList<Integer> scores,ArrayList<String> powers) { 374 exGrade = scores; 375 super.powers=powers; 376 } 377 public int getUsualGrade() { 378 return 0; 379 } 380 public int getTotalGrade(){ 381 float sum=0; 382 for(int i=0;i<exGrade.size();i++){ 383 sum=sum+exGrade.get(i)*Float.parseFloat(powers.get(i)); 384 } 385 return (int)sum; 386 } 387 } 388 class InputMatching { 389 static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 390 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 391 static String scoreMatching = "([1-9]?[0-9]|100)"; 392 static String experimentNum="^[4-9]$"; 393 static String coursePowerNum="[1-9]"; 394 static String powerNum="(^[0-9]*\\.([0-9]{1}\\d*)$)|[1]";//小于或等于1的数 395 static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 396 static String courseTypeMatching = "(选修|必修|实验)"; 397 static String checkCourseTypeMatching = "(考试|考察|实验)"; 398 //courseInput用于定义课程信息模式(正则表达式) 399 static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; 400 //scoreInput用于定义成绩信息模式(正则表达式) 401 static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + 402 scoreMatching ; 403 static String scoreInput2= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + 404 scoreMatching + " " +scoreMatching; 405 static String scoreInput3= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + 406 experimentNum; 407 public InputMatching() { 408 } 409 public int matchingInput(String s) { 410 411 if (matchingCourse(s)) 412 return 1; 413 if (matchingScore(s)|| isExScoreValid(s)) 414 return 2; 415 return 0; 416 417 } 418 419 //课程信息 420 private static boolean matchingCourse(String s) { 421 String letters[]=s.split(" "); 422 if(letters[0].matches(courseNameMatching)&&letters[1].matches(courseTypeMatching) 423 &&letters[2].matches(checkCourseTypeMatching)&&letters[3].matches(coursePowerNum)) 424 { 425 if(letters[2].equals("实验")&&(!letters[3].matches(experimentNum))) 426 return false; 427 for(int i=4;i<letters.length;i++){ 428 if(!letters[i].matches(powerNum)) 429 return false; 430 } 431 return true; 432 } 433 return false; 434 } 435 //成绩信息 436 private static boolean matchingScore(String s) { 437 //System.out.println(match); 438 if(s.matches(scoreInput1)||s.matches(scoreInput2)) 439 return true; 440 return false; 441 } 442 //实验课信息 443 private static boolean isExScoreValid(String s) { 444 String[] info = s.split(" "); 445 String stuNumPattern = "\\d{8}"; // 学号格式为8位数字 446 String stuNamePattern = "[\\u4e00-\\u9fa5]{2,4}"; // 姓名格式为2-4个汉字 447 String courseNamePattern = "[a-zA-Z]+"; // 课程名称格式为英文字母 448 String scorePattern = "\\d{1,2}|100"; // 成绩格式为1-2位数字或100 449 if (info.length < 6 || info.length > 13) { // 实验次数至少4次,不超过9次,因此长度应该在6-13之间 450 return false; 451 } 452 if (!info[0].matches(stuNumPattern) || !info[1].matches(stuNamePattern) || !info[2].matches(courseNamePattern)) { 453 return false; 454 } 455 for (int i = 3; i < info.length; i++) { 456 if (!info[i].matches(scorePattern)) { 457 return false; 458 } 459 } 460 return true; 461 } 462 463 }
类图:
设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩
其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。
源码:
1 //动物发生模拟器 2 public class Main { 3 public static void main(String[] args) { 4 Cat cat = new Cat(); 5 Dog dog = new Dog(); 6 Goat goat = new Goat(); 7 speak(cat); 8 speak(dog); 9 speak(goat); 10 } 11 //定义静态方法speak() 12 public static void speak(Animal animal){ 13 System.out.println(animal.getAnimalClass()+"的叫声:"+animal.shout()); 14 } 15 } 16 17 //定义抽象类Animal 18 abstract class Animal{ 19 public abstract String getAnimalClass(); 20 public abstract String shout(); 21 } 22 //基于Animal类,定义猫类Cat,并重写两个抽象方法 23 class Cat extends Animal{ 24 public String getAnimalClass(){ 25 return "猫"; 26 } 27 public String shout(){ 28 return "喵喵"; 29 } 30 } 31 //基于Animal类,定义狗类Dog,并重写两个抽象方法 32 class Dog extends Animal{ 33 public String getAnimalClass(){ 34 return "狗"; 35 } 36 public String shout(){ 37 return "汪汪"; 38 } 39 } 40 //基于Animal类,定义山羊类Goat,并重写两个抽象方法 41 class Goat extends Animal{ 42 public String getAnimalClass(){ 43 return "山羊"; 44 } 45 public String shout(){ 46 return "咩咩"; 47 } 48 }
这段代码是一个动物发声模拟器,主要涉及到面向对象的知识点,包括抽象类、继承、多态等。 首先,在主函数中创建了一个猫对象、一个狗对象和一个山羊对象,并分别调用了speak方法来输出它们的叫声。 在抽象类Animal中定义了两个抽象方法getAnimalClass和shout,分别用于获取动物的类别和发出叫声。这样做的好处是可以统一处理不同种类的动物,而无需为每个动物类都写一个speak方法。 然后,分别创建了猫类、狗类和山羊类,它们都继承自Animal类,并重写了父类的两个抽象方法。在每个子类中,getAnimalClass方法返回了该动物的类别,shout方法返回了该动物的叫声。 最后,在speak方法中,通过传入Animal类型的参数,实现了多态。无论传入的是猫对象、狗对象还是山羊对象,都可以调用各自类中重写的shout方法,实现了不同动物的发声。 这段代码的难点在于理解抽象类和多态的概念,以及如何正确使用。抽象类是一种不能被实例化的类,只能被继承,用于定义一些共性的方法和属性。多态是指同一个方法在不同的对象上有不同的实现,通过父类的引用指向子类的对象,可以实现对不同子类的统一处理。 代码的改进之处可以考虑增加更多的动物类,以及为每个动物类添加更多的属性和方法,使模拟器更加完善。另外,可以考虑将动物类的属性和方法封装起来,提供更好的访问控制和代码复用性。 总结起来,这段代码通过抽象类和多态的运用,实现了一个动物发声模拟器,展示了面向对象的编程思想。对于初学者来说,理解抽象类和多态的概念是关键,通过实践和不断的练习,可以更好地掌握这些知识点。
类图:
Java每个对象都继承自Object,都有equals、toString等方法。
现在需要定义PersonOverride
类并覆盖其toString
与equals
方法。
1. 新建PersonOverride类
a. 属性:String name
、int age
、boolean gender
,所有的变量必须为私有(private)。
b. 有参构造方法,参数为name, age, gender
c. 无参构造方法,使用this(name, age,gender)
调用有参构造方法。参数值分别为"default",1,true
d.toString()
方法返回格式为:name-age-gender
e. equals
方法需比较name、age、gender,这三者内容都相同,才返回true
.
2. main方法
2.1 输入n1,使用无参构造方法创建n1个对象,放入数组persons1。
2.2 输入n2,然后指定name age gender
。每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果不存在,才将该对象放入数组persons2。
2.3 输出persons1数组中的所有对象
2.4 输出persons2数组中的所有对象
2.5 输出persons2中实际包含的对象的数量
2.5 使用System.out.println(Arrays.toString(PersonOverride.class.getConstructors()));
输出PersonOverride的所有构造方法。
提示:使用ArrayList
代替数组大幅复简化代码,请尝试重构你的代码。
源码:
1 import java.util.*; 2 import java.lang.reflect.*; 3 4 class PersonOverride { 5 private String name; 6 private int age; 7 private boolean gender; 8 9 public PersonOverride(String name, int age, boolean gender) { 10 this.name = name; 11 this.age = age; 12 this.gender = gender; 13 } 14 15 public PersonOverride() { 16 this("default", 1, true); 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public boolean isGender() { 28 return gender; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public void setAge(int age) { 36 this.age = age; 37 } 38 39 public void setGender(boolean gender) { 40 this.gender = gender; 41 } 42 43 public String toString() { 44 return name + "-" + age + "-" + gender; 45 } 46 47 public boolean equals(Object obj) { 48 if (obj instanceof PersonOverride) { 49 PersonOverride other = (PersonOverride) obj; 50 return name.equals(other.name) && age == other.age && gender == other.gender; 51 } 52 return false; 53 } 54 } 55 56 public class Main { 57 public static void main(String[] args) { 58 Scanner scanner = new Scanner(System.in); 59 int n1 = Integer.parseInt(scanner.nextLine()); 60 ArrayList<PersonOverride> persons1 = new ArrayList<>(); 61 for (int i = 0; i < n1; i++) { 62 persons1.add(new PersonOverride()); 63 } 64 int n2 = Integer.parseInt(scanner.nextLine()); 65 ArrayList<PersonOverride> persons2 = new ArrayList<>(); 66 for (int i = 0; i < n2; i++) { 67 String[] parts = scanner.nextLine().split(" "); 68 String name = parts[0]; 69 int age = Integer.parseInt(parts[1]); 70 boolean gender = Boolean.parseBoolean(parts[2]); 71 PersonOverride person = new PersonOverride(name, age, gender); 72 if (!persons2.contains(person)) { 73 persons2.add(person); 74 } 75 } 76 for (PersonOverride person : persons1) { 77 System.out.println(person); 78 } 79 for (PersonOverride person : persons2) { 80 System.out.println(person); 81 } 82 System.out.println(persons2.size()); 83 84 Constructor<?>[] constructors = PersonOverride.class.getDeclaredConstructors(); 85 Arrays.sort(constructors, Comparator.comparing(Constructor::getParameterCount)); 86 87 System.out.println(Arrays.toString(constructors)); 88 } 89 }
这段代码是一个简单的Java程序,主要涉及到类的定义、构造函数、成员变量、方法、ArrayList的使用、Scanner的使用等知识点。 首先,代码定义了一个名为PersonOverride的类,该类有三个私有成员变量name、age和gender,以及一个构造函数和一些getter和setter方法。还有一个重写了toString()方法和equals()方法的方法。 在Main类的main方法中,首先通过Scanner获取输入的n1和n2的值,分别表示要创建的PersonOverride对象的数量。然后使用一个for循环创建n1个默认的PersonOverride对象,并将它们添加到persons1列表中。接着使用另一个for循环创建n2个自定义的PersonOverride对象,并将它们添加到persons2列表中。在创建自定义对象时,通过split()方法将输入的字符串按空格分割成三部分,分别表示name、age和gender的值,然后使用这些值创建PersonOverride对象。在添加到persons2列表之前,通过contains()方法判断该对象是否已经存在于列表中,如果不存在则添加。 这段代码的难点和易错点在于对类的定义和使用的理解,以及对ArrayList和Scanner的使用的熟悉程度。在创建自定义对象时,需要注意输入的格式和类型的转换。另外,equals()方法的重写需要注意对象类型的判断和成员变量的比较。 代码可以改进的地方包括: 1. 可以在PersonOverride类中添加一个构造函数,接收一个字符串作为参数,用于解析字符串并初始化对象的成员变量。 2. 可以在PersonOverride类中添加一个静态方法,用于从控制台获取用户输入并创建PersonOverride对象。 3. 可以在Main类中使用try-catch语句来处理输入错误或格式错误的异常,提高代码的健壮性。 4. 可以在Main类中添加一些其他的操作,例如对persons1和persons2列表的遍历和操作。 总结来说,这段代码涉及到了Java基础的类的定义和使用、ArrayList的使用、Scanner的使用等知识点。难点和易错点在于对类的定义和使用的理解,以及对ArrayList和Scanner的使用的熟悉程度。代码可以改进的地方包括添加更多的功能和异常处理。
类图:
PTA6-8题目集总结:
在完成课程成绩统计程序等题目过程中,我学到了很多关于软件开发的知识和技能。首先,我学会了如何进行需求分析和系统设计。在项目开始之前,我和团队成员一起进行了需求分析,明确了项目的功能和需求。然后,我们进行了系统设计,确定了系统的架构和模块划分。通过这个过程,我学会了如何将抽象的需求转化为具体的系统设计,这对于实际的软件开发非常重要。
其次,我学习了如何使用Java编程语言进行软件开发。在项目中,我使用Java编写了成绩统计程序的各个模块,包括学生信息管理、成绩录入和查询等功能。通过这个过程,我巩固了之前学习的Java知识,并且学会了如何将这些知识应用到实际的项目中。
另外,我还学习了如何进行软件测试和调试。在项目完成之后,我进行了系统测试,确保程序的功能和性能符合需求。在测试过程中,我发现了一些问题,并且通过调试和修复来解决这些问题。通过这个过程,我学会了如何进行软件测试和调试,提高了程序的质量和稳定性。
在项目中,我也遇到了一些挑战和困难。首先,需求的变化和调整是一个挑战。在项目进行过程中,我们发现一些需求需要进行调整和修改,这要求我们及时进行沟通和协调,确保项目的顺利进行。其次,团队合作和沟通也是一个挑战。在项目中,我们需要与团队成员进行有效的沟通和协作,确保项目的进展和质量。
总的来说,通过完成课程成绩统计程序的题目等,我学到了很多关于软件开发的知识和技能,包括需求分析和系统设计、Java编程、软件测试和调试等。同时,我也面对了一些挑战和困难,但通过团队合作和努力,最终完成了项目。这个项目经验对于我今后的软件开发和项目管理都非常有帮助,我相信我能够在实际的工作中运用这些知识和技能,取得更好的成绩。
对于三个题目集方面,我有以下改进建议和意见:
1. 提供更详细的题目说明:有时候题目的表述可能不够清晰,容易引起理解上的困惑。建议在题目中提供更详细的说明和示例,以帮助学生更好地理解题意。
2. 强调编码规范和最佳实践:在题目的要求中可以加入对编码规范和最佳实践的要求,例如命名规范、注释要求、代码风格等。这有助于培养良好的编码习惯和提高代码的可读性和可维护性。
3. 提供范例代码和解析:对于每个题目,可以提供范例代码和解析,以便学生参考和学习。这有助于学生理解问题的解决思路和方法。
综合性总结:
这段时间学习Java,我收获了很多知识和技能。首先,我学会了Java的基本语法和面向对象的编程思想。通过学习Java的数据类型、控制流程、数组、类和对象等基础知识,我能够编写简单的Java程序,并且能够理解和分析他人编写的代码。
其次,我学习了Java的核心类库和常用API。Java的标准类库提供了丰富的功能和工具,如集合框架、IO操作、多线程、网络编程等。通过学习这些类库和API,我能够更高效地开发Java应用程序,并且能够解决一些常见的编程问题。
另外,我也学习了Java的异常处理机制和文件操作。异常处理是Java中重要的编程概念,通过学习异常处理,我能够编写更健壮的程序,并且能够更好地处理程序中可能出现的错误。文件操作是Java中常用的功能之一,通过学习文件操作,我能够读写文件、创建目录、删除文件等,这对于实际开发中的数据存储和读取非常有用。
在学习过程中,我也发现了一些需要进一步学习和研究的地方。首先,我需要深入学习Java的多线程编程。多线程是Java中重要的特性之一,通过使用多线程,可以实现程序的并发执行,提高程序的性能。但是多线程编程也存在一些问题,如线程安全、死锁等,我需要进一步学习和理解这些问题,并且学会如何解决它们。
其次,我还需要学习Java的网络编程和数据库操作。网络编程是现代应用开发中不可或缺的一部分,通过学习网络编程,我能够实现网络通信、数据传输等功能。数据库操作是Java应用开发中常用的功能之一,通过学习数据库操作,我能够实现数据的存储和读取,并且能够使用数据库来支持应用程序的功能。
总的来说,这段时间学习Java让我对这门语言有了更深入的了解,我学会了Java的基本语法和面向对象的编程思想,掌握了Java的核心类库和常用API,也学习了Java的异常处理和文件操作。但是我也意识到还有很多需要进一步学习和研究的地方,如多线程编程、网络编程和数据库操作等。通过不断学习和实践,我相信我能够更好地掌握Java编程技术,并且能够在实际开发中运用自如。
意见与建议:
作为学生,我对Java课程的教师、课程内容、作业、实验以及课上和课下的组织方式有一些改进建议和意见。
首先,关于教师方面,我认为教师应该具备扎实的Java编程知识和丰富的实践经验。他们应该能够清晰地传授Java的基本概念和核心知识,并能够引导学生进行实际的编程练习和项目开发。此外,教师应该积极与学生互动,鼓励学生提问和参与讨论,以激发学生的学习兴趣和思考能力。
其次,关于课程内容方面,我建议在设计课程大纲时,应该充分考虑到学生的实际需求和就业市场的需求。课程内容应该包括Java语言的基础知识、面向对象编程、数据结构与算法、多线程编程、网络编程等方面的内容。同时,可以适当引入一些实际应用案例,让学生能够将所学知识应用到实际项目中。
第三,关于作业和实验方面,我认为应该注重实践能力的培养。作业和实验应该具有一定的难度和挑战性,能够让学生运用所学知识解决实际问题。同时,作业和实验应该有明确的要求和评分标准,以便学生能够清楚地知道自己的学习进展和不足之处。
第四,关于课上和课下的组织方式,我建议采用多种教学方法和手段。除了传统的讲授和演示,可以引入案例分析、小组讨论、编程实践等方式,以提高学生的学习效果和参与度。此外,可以利用在线学习平台和资源,提供课程资料、习题和编程练习等,方便学生在课下进行自主学习和巩固。
总之,我希望Java课程能够更加注重实践能力的培养,教师能够具备扎实的专业知识和教学经验,课程内容能够紧密结合实际应用,作业和实验能够有针对性和挑战性,课上和课下的组织方式能够多样化和灵活性。相信通过这些改进和优化,Java课程将能够更好地满足学生的学习需求,提高学生的编程能力和就业竞争力。