以下是对PTA6到8的总结
前言:
在这个学期第一次接触java语言,到现在看来,在面向对象之前所学的C语言和java只有部分的语法差别,不同的语言肯定有不同的语法规则。而在接触面向对象之后,java的特点才会展现出来;继承,多态以及封装。私以为只要有关面对对象的的编程思维转变过来理解过来,java就不会太难。
第六次题目集:
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重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)成绩平均分只取整数部分,小数部分丢弃
参考类图:
在这里说一下这次java作业的主要特点与难点:
在这里主要说一下java的主要要点:
-
复杂度分析:算法的时间复杂度、空间复杂度等分析是非常关键的,也是许多算法题目的重点。
-
递归思想:递归算法在解决某些问题时非常高效,并且思路简单清晰,但是递归调用栈的深度过大可能会导致栈溢出。
-
数据结构选择:Java提供了丰富的数据结构,如数组、链表、堆等等。但是在实际问题中要选用合适的数据结构才能发挥算法的最优性能。
-
算法设计思想:有很多经典算法思想如贪心、动态规划、分治、回溯等,这些算法并不是很好理解,需要进行反复思考和练习。
-
Java类库使用:Java的集合框架、IO操作等相关API的使用对于算法代码的实现也至关重要。需要熟悉这些API的特点以及如何灵活运用API来解决问题。
以下是我应用这些原理写出的代码:
import java.text.Collator; import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { Scanner s = new Scanner(System.in); String s_record = s.nextLine(); ParseInput handle=new ParseInput(); while (!s_record.equals("end")) { handle.parseInput(s_record);//解析用户输入的每一行数据 s_record = s.nextLine(); } handle.showStudents(); handle.showCourses(); handle.showClasses(); } } class ParseInput{ ArrayList<Student> listStudent=new ArrayList<>(); ArrayList<Course> listCourse=new ArrayList<>(); ArrayList<ClassRoom> listClassRooms =new ArrayList<>(); ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>(); public void parseInput(String line) { InputMatching mat=new InputMatching(); int flag=mat.matchingInput(line); if(flag == 0){ System.out.println("wrong format"); } else if(flag == 1){ courseMessage(line); } else if (flag == 2 ) { gradeMessage(line); } }//输入 public void courseMessage(String line){ String letters[]=line.split(" "); String courseName = letters[0],kind = letters[1],testKind = letters[2]; //课程名,课程类型,课程考试类型 Course course=new Course(courseName,kind,testKind); if(checkCourse(course)){ if(searchCourse(courseName)!=null)return; else listCourse.add(course); } } public void gradeMessage(String line){ String items[]=line.split(" "),stuId= items[0],classID= items[0].substring(0,6),name=items[1],courseName=items[2]; if(searchClass(classID)==null){ ClassRoom cla=new ClassRoom(classID); listClassRooms.add(cla); } Student stu=new Student(classID,stuId,name); if(searchStudent(stuId)) { return; } listStudent.add(stu); Course course = searchCourse(courseName); if (course == null) { System.out.println(courseName + " does not exist"); return; } if (items.length == 4 && course.method.equals("考察")) { int finalGrade = Integer.parseInt(items[3]); AssessGrade assessGrade = new AssessGrade(finalGrade); ChooseCourse chooseCourse = new ChooseCourse(course, stu, assessGrade); if (!searchChooseCourse(name, courseName)) { listChooseCourse.add(chooseCourse); } } else if (items.length == 5 && course.method.equals("考试")) { int usualGrade = Integer.parseInt(items[3]); int finalGrade = Integer.parseInt(items[4]); ExamGrade examGrade = new ExamGrade(usualGrade, finalGrade); ChooseCourse chooseCourse = new ChooseCourse(course, stu, examGrade); listChooseCourse.add(chooseCourse); } else { System.out.println(stuId + " " + name + " : access mode mismatch"); } } public boolean checkCourse(Course course){ int flag1 = -1; int flag2 = -1; String kindOfCourse = course.getKind(); if ("必修".equals(kindOfCourse)) { flag1 = 0; } else if ("选修".equals(kindOfCourse)) { flag1 = 1; } String methodOfCourse = course.getMethod(); if ("考试".equals(methodOfCourse)) { flag2 = 0; } else if ("考察".equals(methodOfCourse)) { flag2 = 1; } if ((flag1 == 0 && flag2 == 0) || (flag1 == 1 && (flag2 == 0 || flag2 == 1))) { return true; } else { System.out.println(course.getName() + " : course type & access mode mismatch"); return false; } } public ClassRoom searchClass(String classId){ for(ClassRoom cls: listClassRooms){ if(cls.getClassId().equals(classId)) return cls; } return null; } public Course searchCourse(String name){ for(Course course:listCourse){ if(course.getName().equals(name)) return course; } return null; } //是否重复学生 public boolean searchStudent(String id){ for(Student stu:listStudent){ if(stu.getsNumber().equals(id)) return true; } return false; } //查找是否有重复选课成绩 public boolean searchChooseCourse(String stuName,String courseName){ for(ChooseCourse cs:listChooseCourse){ if(cs.student.getStuName().equals(stuName)&&cs.course.getName().equals(courseName)) return true; } return false; } public void showStudents(){ Collections.sort(listStudent); for(int i=0;i<listStudent.size();i++){ Student stu=listStudent.get(i); //从总选课表listChooseCourse中获取该生的选课记录 ArrayList<ChooseCourse> stuCourseSelects=getStudentSelects(stu.getsNumber()); if(stuCourseSelects.size()!=0) { System.out.println(stu.getsNumber()+" "+stu.getStuName()+" "+ gAvScore(stuCourseSelects)); } else if(stuCourseSelects.size()==0){ System.out.println(stu.getsNumber()+" "+stu.getStuName()+" "+"did not take any exams"); } } } public void showCourses(){ Collections.sort(listCourse); for(int i=0;i<listCourse.size();i++){ Course course=listCourse.get(i); ArrayList<ChooseCourse> stuCourseSelects=getCourseSelects(course.getName()); if(stuCourseSelects.size()!=0){ if(course.method.equals("考试")) System.out.println(course.getName()+" "+ gAUScore(stuCourseSelects)+" "+ gAFScore(stuCourseSelects)+" "+ gAvScore(stuCourseSelects)); if(course.method.equals("考察")) System.out.println(course.getName()+" "+ gAFScore(stuCourseSelects)+" "+ gAvScore(stuCourseSelects)); } else if(stuCourseSelects.size()==0){ System.out.println(course.name +" "+"has no grades yet"); } } } public void showClasses(){ Collections.sort(listClassRooms); for (ClassRoom cls : listClassRooms) { ArrayList<ChooseCourse> stuCourseSelects = getClassSelects(cls.getClassId()); if (!stuCourseSelects.isEmpty()) { System.out.println(cls.getClassId() + " " + gAvScore(stuCourseSelects)); } else { System.out.println(cls.getClassId() + " has no grades yet"); } } } public ArrayList<ChooseCourse> getStudentSelects(String id) { return listChooseCourse.stream() .filter(cos -> cos.student.getsNumber().equals(id)) .collect(Collectors.toCollection(ArrayList::new)); } public ArrayList<ChooseCourse> getCourseSelects(String courseName){ ArrayList<ChooseCourse> choose=new ArrayList<>(); for(ChooseCourse cos:listChooseCourse) { if (cos.course.getName().equals(courseName)) choose.add(cos); } return choose; } public ArrayList<ChooseCourse> getClassSelects(String clsId){ ArrayList<ChooseCourse> choose =new ArrayList<>(); for(ChooseCourse cos:listChooseCourse) { if (cos.student.getClsName().equals(clsId)) choose.add(cos); } return choose; } /////////////////////////////////////////////////////////// public int gAvScore(ArrayList<ChooseCourse> cs){ int sum = 0; for (int i = 0; i < cs.size(); i++) { // use an explicit loop instead of a stream ChooseCourse c = cs.get(i); // get the element at index i int totalGrade = c.grade.getTotalGrade(); sum += totalGrade; // accumulate the total grade } if (cs.size() == 0) { // explicitly check if the list is empty return 0; } else { int average = sum / cs.size(); // calculate the average return average; } } public int gAUScore(ArrayList<ChooseCourse> cs){ int sum = cs.stream() .filter(c -> c.course.getMethod().equals("考试")) .mapToInt(c -> c.grade.getUsualGrade()) .sum(); return (cs.size() == 0) ? 0 : sum / cs.size(); } public int gAFScore(ArrayList<ChooseCourse> cs){ int sum = cs.stream().mapToInt(c -> c.grade.finalGrade).sum(); return (cs.size() == 0) ? 0 : sum / cs.size(); } } class ChooseCourse{ Course course; Student student; Grade grade; public ChooseCourse(Course course,Student student,Grade grade) { this.course = course; this.student=student; this.grade=grade; } } class Student implements Comparable<Student>{ String stuName; String sNumber; String clsName; public String getsNumber(){ return sNumber; } public String getStuName(){ return stuName; } public String getClsName(){ return clsName; } public Student(String clsName, String sNumber, String stuName) { this.clsName = clsName; this.sNumber = sNumber; this.stuName=stuName; } public int compareTo(Student stu){ return getsNumber().compareTo(stu.getsNumber()); } String score; public Student(String score) { this.score = score; } public String getScore() { return score; } public void setScore(String score) { this.score = score; } } class Course implements Comparable<Course>{ String name; String kind; String method; public Course() { } public Course(String name, String kind, String method) { this.name = name; this.kind = kind; this.method = method; } public String getName(){ return name; } public String getKind(){ return kind; } public String getMethod(){ return method; } @Override public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(name,o.getName()); } } class ClassRoom implements Comparable<ClassRoom>{ String classId; public ClassRoom() { } public String getClassId(){ return classId; } public ClassRoom(String classId) { this.classId = classId; } @Override public int compareTo(ClassRoom o) { return getClassId().compareTo(o.getClassId()); } } abstract class Grade{ int finalGrade; public Grade() { } public abstract int getUsualGrade(); public abstract int getTotalGrade(); } class ExamGrade extends Grade{ int usualGrade; public ExamGrade(int usualGrade,int finalGrade) { this.usualGrade=usualGrade; this.finalGrade=finalGrade; } public int getUsualGrade(){ return usualGrade; } public int getFinalGrade(){ return 0; } public int getTotalGrade(){ return (int)(usualGrade*0.3+finalGrade*0.7); } } class AssessGrade extends Grade{ public AssessGrade(int finalGrade) { this.finalGrade=finalGrade; } public int getFinalGrade(){ return finalGrade; } @Override public int getUsualGrade() { return 0; } public int getTotalGrade(){ return finalGrade; } } class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修)"; static String checkCourseTypeMatching = "(考试|考察)"; //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ; static String scoreInput2= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " +scoreMatching; public InputMatching() { } public int matchingInput(String s) { if (matchingCourse(s)) return 1; if (matchingScore(s)) return 2; return 0; } //课程信息 private static boolean matchingCourse(String s) { return s.matches(courseInput); } //成绩信息 private static boolean matchingScore(String s) { //System.out.println(match); if(s.matches(scoreInput1)||s.matches(scoreInput2)) return true; return false; } }
第七次题目集:
这里涉及到有关hashmap的系列知识点与题目:
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
使用HashMap存储学生信息,并实现根据学号的检索功能
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
end之后输入某个学号,执行程序输出该生的详细信息
输出格式:
输出查询到的学生信息格式:学号+英文空格+姓名+英文空格+成绩
如果没有查询到,则输出:"The student "+查询的学号+" does not exist"
import java.util.HashMap; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); HashMap<Integer, String[]> students = new HashMap<>(); // 输入学生信息,保存到HashMap中 while (true) { String input = in.nextLine(); if (input.equals("end")) { break; } String[] info = input.split(" "); int id = Integer.parseInt(info[0]); String name = info[1]; int score = Integer.parseInt(info[2]); String[] details = {name, Integer.toString(score)}; students.put(id, details); } // 根据学号查询学生信息 String query = in.nextLine(); if (students.containsKey(Integer.parseInt(query))) { String[] info = students.get(Integer.parseInt(query)); System.out.println(query + " " + info[0] + " " + info[1]); } else { System.out.println("The student " + query + " does not exist"); } } }
第二题也是有关hashmap的题目
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
要求:使用HashMap存储学生信息。
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
输出格式:
按学号从大到小的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+成绩
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); HashMap<Integer, String[]> students = new HashMap<>(); Student student = new Student(); // 输入学生信息,保存到HashMap中 while (true) { String input = in.nextLine(); if (input.equals("end")) { break; } String[] info = input.split(" "); int id = Integer.parseInt(info[0]); student.stuId.add(Integer.valueOf(info[0])); String name = info[1]; int score = Integer.parseInt(info[2]); String[] details = {name, Integer.toString(score)}; students.put(id, details); } // 根据学号查询学生信息 Collections.sort(student.stuId); for(int i = student.stuId.size()-1; i>-1;i--){ if (students.containsKey(Integer.parseInt(String.valueOf(student.stuId.get(i))))) { String[] info = students.get(Integer.parseInt(String.valueOf(student.stuId.get(i)))); System.out.println((Integer.parseInt(String.valueOf(student.stuId.get(i)))) + " " + info[0] + " " + info[1]); } else { System.out.println("The student " + (Integer.parseInt(String.valueOf(student.stuId.get(i)))) + " does not exist"); } } } } class Student{ String Number; String Name; String Score; ArrayList<Integer> stuId= new ArrayList<>(); }
在这里涉及了以下有关hashmap的知识点:
HashMap 是 Java 中常用的集合类之一,它基于哈希表实现,提供了高效的插入、查找和删除操作。以下是 HashMap 的主要知识点:
1. 哈希表原理:HashMap 内部通过一个数组和链表/红黑树来实现。每个元素由键值对 (Key-Value) 组成,通过将 Key 的哈希值映射到数组索引上,并使用链表或红黑树处理哈希冲突。
2. Key 的唯一性:HashMap 的 Key 是唯一的,即同一个 HashMap 中不能存在重复的 Key。如果插入了相同的 Key,则后面的 Value 会覆盖前面的 Value。
3. 线程不安全:HashMap 是非线程安全的,如果需要在多线程环境中使用,可以考虑使用 ConcurrentHashMap。
4. 添加元素:使用 `put(key, value)` 方法向 HashMap 中添加元素,将 Key 和 Value 作为参数传递给该方法。
5. 获取元素:使用 `get(key)` 方法从 HashMap 中获取元素,传入 Key 返回对应的 Value。如果 Key 不存在,则返回 null。
6. 删除元素:使用 `remove(key)` 方法从 HashMap 中删除元素,传入 Key 来指定要删除的元素。删除成功返回被删除的 Value,如果 Key 不存在则返回 null。
7. 遍历元素:可以通过迭代器(Iterator)或者增强型 for 循环遍历 HashMap 的元素。可以使用 `entrySet()` 方法获取键值对的集合,然后对集合进行遍历。
8. 初始容量和负载因子:HashMap 具有初始容量和负载因子两个属性。初始容量指的是 HashMap 创建时内部数组的大小,默认为 16。负载因子表示在数组存储元素的过程中,达到什么程度触发扩容,默认为 0.75。
9. 扩容机制:当 HashMap 中的元素数量超过容量与负载因子的乘积时,会自动进行扩容,以保持较低的哈希冲突率和较高的查询效率。
10. 效率注意事项:选择合适的初始容量和负载因子能够提高 HashMap 的性能。同时,尽量使用不可变类型作为 Key,避免在计算哈希值时出现变化。
HashMap 在 Java 中是常用且重要的数据结构之一,了解它的原理和使用方式能够帮助开发者更好地利用 HashMap 实现各种功能。
此外,这里还涉及到了java语言中的多态题目:
设计一个动物发生模拟器,用于模拟不同动物的叫声。比如狮吼、虎啸、狗旺旺、猫喵喵……。
定义抽象类Animal,包含两个抽象方法:获取动物类别getAnimalClass()、动物叫shout();
然后基于抽象类Animal定义狗类Dog、猫类Cat和山羊Goat,用getAnimalClass()方法返回不同的动物类别(比如猫,狗,山羊),用shout()方法分别输出不同的叫声(比如喵喵、汪汪、咩咩)。
最后编写AnimalShoutTest类测试,输出:
猫的叫声:喵喵
狗的叫声:汪汪
山羊的叫声:咩咩
其中,在AnimalShoutTestMain类中,用speak(Animal animal){}方法输出动物animal的叫声,在main()方法中调用speak()方法,分别输出猫、狗和山羊对象的叫声。
以下是我的代码:
//动物发生模拟器. 请在下面的【】处添加代码。 public class Main { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); Goat goat = new Goat(); speak(cat); speak(dog); speak(goat); } //定义静态方法speak() static void speak(Animal animal){ animal.shout(); } } //定义抽象类Animal abstract class Animal{ abstract Animal getAnimalClass(); abstract void shout(); } //基于Animal类,定义猫类Cat,并重写两个抽象方法 class Cat extends Animal{ Cat cat; @Override void shout() { System.out.println("猫的叫声:喵喵"); } @Override Cat getAnimalClass() { return cat; } } //基于Animal类,定义狗类Dog,并重写两个抽象方法 class Dog extends Animal{ Dog dog; @Override void shout() { System.out.println("狗的叫声:汪汪"); } @Override Dog getAnimalClass() { return dog; } } //基于Animal类,定义山羊类Goat,并重写两个抽象方法 class Goat extends Animal{ Goat goat; @Override void shout() { System.out.println("山羊的叫声:咩咩"); } @Override Goat getAnimalClass() { return goat; } }
在这道题目中还涉及了这些多态的知识点:
当谈到Java中的多态时,有几个关键知识点需要了解。
1. **继承与多态:** 多态是基于继承的概念。在Java中,我们可以使用继承创建父类和子类之间的关系。子类可以继承父类的属性和方法。当我们声明一个父类对象引用指向一个子类对象时,就会发生多态。这意味着通过该引用可以访问父类和子类之间共享的方法,但无法直接访问子类特有的方法。
2. **方法重写:** 子类可以重写(覆盖)从父类继承的方法。重写方法的签名(名称、参数列表)必须与父类中的方法相同。通过重写方法,子类可以提供自己的实现逻辑,并且在运行时根据具体对象类型决定哪个版本的方法将被调用。
3. **动态绑定:** 在多态中,方法的调用是在运行时动态确定的,而不是在编译时。这称为动态绑定或后期绑定。通过动态绑定,程序可以根据对象的真实类型去调用相应的方法,即使是通过父类引用来访问。这种灵活性使得代码更具扩展性和可重用性。
4. **抽象类和接口:** 多态还可以通过抽象类和接口实现。抽象类是无法实例化的,只能被继承。它可以包含抽象方法,子类必须实现这些抽象方法。接口定义了一组可以由实现类来实现的方法。通过使用抽象类或接口,可以使用多态的特性传递参数、声明引用和创建对象。
总体而言,Java中的多态为面向对象编程提供了更灵活和可扩展的方式。通过使用多态,我们可以根据具体对象的类型来调用相应的方法,使代码更清晰、可重用和易于维护。
然后我们接着看我们的课程类例题:
课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
import java.text.Collator; import java.util.*; public class Main { public static void main(String[] args) { Scanner s = new Scanner(System.in); String s_record = s.nextLine(); ParseInput handle=new ParseInput(); while (!s_record.equals("end")) { handle.parseInput(s_record);//解析用户输入的每一行数据 s_record = s.nextLine(); } handle.showStudents(); handle.showCourses(); handle.showClasses(); } } class ParseInput{ ArrayList<Student> listStudent=new ArrayList<>(); ArrayList<Course> listCourse=new ArrayList<>(); ArrayList<Class> listClass=new ArrayList<>(); ArrayList<ChooseCourse> listChooseCourse=new ArrayList<>(); public void parseInput(String line){ InputMatching mat=new InputMatching(); int flag=mat.matchingInput(line); //System.out.println(flag); if(flag == 0){ System.out.println("wrong format"); } else if(flag == 1){ courseMessage(line); } else if (flag == 2 ) { gradeMessage(line); } }//输入 public void courseMessage(String str){ String letters[]=str.split(" "); String courseName=letters[0];//课程名 String type=letters[1];//课程类型 String testType=letters[2];//课程考试类型 Course course=new Course(courseName,type,testType); if(checkCourse(course)){ if(searchCourse(courseName)!=null) listCourse.add(course); } } public void gradeMessage(String str){//已修改 String letters[]=str.split(" "); String stuId= letters[0];//学生学号 String classID= letters[0].substring(0,6); String name=letters[1];//学生姓名 String courseName=letters[2];//课程名字 //如果该班级第一次出现 if(searchClass(classID)==null){ Class cla=new Class(classID); listClass.add(cla); } Student stu=new Student(classID,stuId,name); listStudent.add(stu);//将学生加入列表中 //课程是否存在 if(searchCourse(courseName)==null){ System.out.println(courseName+" "+"does not exist"); } //当课程存在时 else if(searchCourse(courseName)!=null){ Course course=searchCourse(courseName); //考察 if(letters.length==4&&course.testType.equals("考察")){ int finalGrade= Integer.parseInt(letters[3]); AssessGrade assessGrade=new AssessGrade(finalGrade); ChooseCourse chooseCourse=new ChooseCourse(course,stu,assessGrade); if(!searchChooseCourse(name,courseName)) listChooseCourse.add(chooseCourse); } //考试 else if(letters.length==5&&course.testType.equals("考试")){ int usualGrade= Integer.parseInt(letters[3]); int finalGrade= Integer.parseInt(letters[4]); ExamGrade examGrade=new ExamGrade(usualGrade,finalGrade); ChooseCourse chooseCourse=new ChooseCourse(course,stu,examGrade); listChooseCourse.add(chooseCourse); } //实验 else if(letters.length>5&&letters.length<14&&course.testType.equals("实验")){ ArrayList<Integer> sum = new ArrayList<>(); for(int i = 4; i < letters.length;i++) {//添加每次成绩进数组 sum.add(Integer.valueOf(letters[i])); } AverageGrade averageGrade = new AverageGrade(sum); ChooseCourse chooseCourse=new ChooseCourse(course,stu,averageGrade); listChooseCourse.add(chooseCourse); } else{ //学号+英文空格+姓名+英文空格+": access mode mismatch" System.out.println(stuId+" "+name+" "+": access mode mismatch"); } } } public boolean checkCourse(Course course){//已修改 int flag1,flag2; switch(course.getType()){//获取课程类型 case "必修":flag1=0;break; case "选修":flag1=1;break; case "实验":flag1=2;break; default:flag1=-1;break; } switch(course.getTestType()){//获取课程考核方式 case "考试":flag2=0;break; case "考察":flag2=1;break; case "实验":flag2=2;break; default:flag2=-1;break; } if(flag1==0&&flag2==0)//考试 return true; if(flag1==1&&(flag2==0||flag2==1))//考察 return true; if(flag1==2&&flag2==2)//实验 return true; System.out.println(course.getCourseName()+" : course type & access mode mismatch"); return false; } public Class searchClass(String classId){ for(Class cls:listClass){ if(cls.getClassId().equals(classId)) return cls; } return null; } public Course searchCourse(String name){ for(Course course:listCourse){ if(course.getCourseName().equals(name)) return course; } return null; } public void showStudents(){ Collections.sort(listStudent); for(int i=0;i<listStudent.size();i++){ Student stu=listStudent.get(i); //从总选课表listChooseCourse中获取该生的选课记录 ArrayList<ChooseCourse> stuCourseSelects=getStudentSelects(stu.getId()); if(stuCourseSelects.size()!=0) { System.out.println(stu.getId()+" "+stu.getStuName()+" "+getAvgTotalScore(stuCourseSelects)); } else if(stuCourseSelects.size()==0){ System.out.println(stu.getId()+" "+stu.getStuName()+" "+"did not take any exams"); } } } public boolean searchChooseCourse(String stuName,String courseName){ for(ChooseCourse cs:listChooseCourse){ if(cs.student.getStuName().equals(stuName)&&cs.course.getCourseName().equals(courseName)) return true; } return false; } public void showCourses(){ Collections.sort(listCourse); for(int i=0;i<listCourse.size();i++){ Course course=listCourse.get(i); ArrayList<ChooseCourse> stuCourseSelects=getCourseSelects(course.getCourseName()); if(stuCourseSelects.size()!=0){ if(course.testType.equals("考试")) System.out.println(course.getCourseName()+" "+getAvgUsualScore(stuCourseSelects)+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects)); if(course.testType.equals("考察")) System.out.println(course.getCourseName()+" "+getAvgFinalScore(stuCourseSelects)+" "+getAvgTotalScore(stuCourseSelects)); if(course.testType.equals("实验")) System.out.println(course.getCourseName()+" "+getAvgTotalScore(stuCourseSelects)); } else if(stuCourseSelects.size()==0){ System.out.println(course.courseName+" "+"has no grades yet"); } } } public void showClasses(){ Collections.sort(listClass); for(int i=0;i<listClass.size();i++){ Class cls=listClass.get(i); ArrayList<ChooseCourse> stuCourseSelects=getClassSelects(cls.getClassId()); if(stuCourseSelects.size()!=0){ System.out.println(cls.getClassId()+" "+getAvgTotalScore(stuCourseSelects)); } else if(stuCourseSelects.size()==0){ System.out.println(cls.getClassId()+" "+"has no grades yet"); } } } public ArrayList<ChooseCourse> getStudentSelects(String id){ ArrayList<ChooseCourse> choose=new ArrayList<>(); for(ChooseCourse cos:listChooseCourse) { if (cos.student.getId().equals(id)) choose.add(cos); } return choose; } public ArrayList<ChooseCourse> getCourseSelects(String courseName){ ArrayList<ChooseCourse> choose=new ArrayList<>(); for(ChooseCourse cos:listChooseCourse) { if (cos.course.getCourseName().equals(courseName)) choose.add(cos); } return choose; } public ArrayList<ChooseCourse> getClassSelects(String clsId){ ArrayList<ChooseCourse> choose =new ArrayList<>(); for(ChooseCourse cos:listChooseCourse) { if (cos.student.getClsId().equals(clsId)) choose.add(cos); } return choose; } public int getAvgTotalScore(ArrayList<ChooseCourse> cs){ int average=0; int sum=0; for(ChooseCourse c:cs){ sum+=c.grade.getTotalGrade(); } average=sum/cs.size(); return average; } public int getAvgUsualScore(ArrayList<ChooseCourse> cs){ int average=0; int sum=0; for(ChooseCourse c:cs){ if(c.course.getTestType().equals("考试")){ sum+=c.grade.getUsualGrade(); } } average=sum/cs.size(); return average; } public int getAvgFinalScore(ArrayList<ChooseCourse> cs){ int average=0; int sum=0; for(ChooseCourse c:cs){ sum+=c.grade.finalGrade; } average=sum/cs.size(); return average; } } class ChooseCourse{ Course course; Student student; Grade grade; public ChooseCourse(Course course,Student student,Grade grade) { this.course = course; this.student=student; this.grade=grade; } } class Student implements Comparable<Student>{ String stuName; String id; String clsId; public String getId(){ return id; } public String getStuName(){ return stuName; } public String getClsId(){ return clsId; } public Student(String clsId,String id,String stuName) { this.clsId=clsId; this.id=id; this.stuName=stuName; } public int compareTo(Student stu){ return getId().compareTo(stu.getId()); } } class Course implements Comparable<Course>{ String courseName; String type; String testType; public Course() { } public Course(String courseName,String type,String testType) { this.courseName=courseName; this.type=type; this.testType=testType; } public String getCourseName(){ return courseName; } public String getType(){ return type; } public String getTestType(){ return testType; } @Override public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(courseName,o.getCourseName()); } } class Class implements Comparable<Class>{ String classId; public Class() { } public String getClassId(){ return classId; } public Class(String classId) { this.classId = classId; } @Override public int compareTo(Class o) { return getClassId().compareTo(o.getClassId()); } } //以下是考试种类 abstract class Grade{ int finalGrade; public Grade() { } public abstract int getUsualGrade(); public abstract int getTotalGrade(); } class ExamGrade extends Grade{//考试成绩 int usualGrade; public ExamGrade(int usualGrade,int finalGrade) { this.usualGrade=usualGrade; this.finalGrade=finalGrade; } public int getUsualGrade(){ return usualGrade; } public int getFinalGrade(){ return 0; } public int getTotalGrade(){ return (int)(usualGrade*0.3+finalGrade*0.7); } } class AssessGrade extends Grade{//考察成绩 public AssessGrade(int finalGrade) { this.finalGrade=finalGrade; } public int getFinalGrade(){ return finalGrade; } @Override public int getUsualGrade() { return 0; } public int getTotalGrade(){ return finalGrade; } } class AverageGrade extends Grade{//实验成绩 ArrayList<Integer> exScore = new ArrayList<>(); int normalGrade; public int getNormalGrade() { return normalGrade; } public AverageGrade(ArrayList<Integer> scores) { exScore =scores; } public int getTotalGrade(){ int sum=0; for(int i = 0; i< exScore.size(); i++){ sum=sum+ exScore.get(i); } int average=sum/ exScore.size(); return average; } @Override public int getUsualGrade() { return 0; } } //////////////////////////////// class InputMatching { static String stuNumMatching = "[0-9]{8}";//8个0-9的数字,学号 static String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String scoreMatching = "([1-9]?[0-9]|100)"; static String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 static String courseTypeMatching = "(选修|必修|实验)"; static String checkCourseTypeMatching = "(考试|考察|实验)"; static String examineNumber = "[4-9]";//实验次数,4到九 //------------------------报错类型匹配------------------------------- static String scoreWorse1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + examineNumber + " " + scoreMatching ;//实验 static String scoreWorse2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + examineNumber + " " + scoreMatching + " " + scoreMatching ;//实验 static String scoreWorse3 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + examineNumber + " " + scoreMatching + " " + scoreMatching + " " +scoreMatching ;//实验 //----------------后面需修改------------------------------- //courseInput用于定义课程信息模式(正则表达式) static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; //scoreInput用于定义成绩信息模式(正则表达式) static String scoreInput1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching ;//考察 static String scoreInput2= stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " +scoreMatching;//考试 static String experimentNum="^[4-9]$"; //////// public InputMatching() { } public int matchingInput(String s) { if (matchingCourse(s))//输入成绩 return 1; if (matchingScore(s)||matchingExScore(s))//输入分数 return 2; return 0; } //课程信息 private static boolean matchingCourse(String s) { return s.matches(courseInput); } //成绩信息 private static boolean matchingScore(String s) { //System.out.println(match); if(s.matches(scoreInput1)||s.matches(scoreInput2)) return true; return false; } private static boolean matchingWorse(String s){ if(s.matches(scoreWorse1)||s.matches(scoreWorse2)||s.matches(scoreWorse3)) return true; return false; } private static boolean matchingExScore(String s){ String letters[]=s.split(" "); if(letters[0].matches(stuNumMatching)&&letters[1].matches(stuNameMatching)&&letters[2].matches(courseNameMatching)&&letters[3].matches(experimentNum)){ for(int i=4;i<letters.length;i++){ if(!letters[i].matches(scoreMatching)) return false; } return true; } return false; } }
这里我理解的java面向对象的难点:
Java面向对象的难点包括以下几个方面:
-
面向对象思想:面向对象思想是Java程序设计的核心基础。理解面向对象的概念,如封装、继承和多态等,是Java程序设计的难点之一。
-
类与对象的关系: 在Java中,类是对象的模板或蓝图,可以用来创建对象。 理解类和对象的概念以及它们之间的关系并熟练掌握类的定义和对象的创建是Java程序设计必须掌握的核心知识点。
-
重载与重写: Java中支持方法的重载和重写,这也是面向对象编程的一个重要特征。重载和重写的区别、如何进行方法的重载和重写等都需要认真学习和练习。
-
继承: 继承是Java中复用代码的一种方式。子类继承父类的属性和行为,从而实现代码的复用和扩展。处理好继承关系、确保代码的高扩展性和低耦合性是设计优秀Java程序的难度所在。
-
异常处理:在Java语言中,异常是标准抛出机制来捕捉和处理错误。对于各种类型的异常,从处理到打印堆栈跟踪都需要掌握
之后就是这次最后的一次题目集了:
这里涉及了arraylist,和日期类的用法:
以下是它的知识点(这里因为题目比较简单,所以省去几题目):
ArrayList 是 Java 中的一个常用类,提供了动态数组的实现。以下是一些关键知识点:
1. **动态数组:** ArrayList 是一个可调整大小的数组,它可以根据需要自动增长或缩小。与传统的数组相比,ArrayList 不需要手动管理容量和索引,并且能够在运行时自由地添加、删除和修改元素。
2. **泛型支持:** ArrayList 支持使用泛型,即在声明 ArrayList 时指定元素类型。这样可以在编译时进行类型检查,并且避免了在获取元素时进行类型转换的麻烦。例如,`ArrayList<Integer>` 表示只能存储整数类型的元素。
3. **常用方法:** ArrayList 提供了一系列常用的方法来操作数据,包括添加(`add()`)、获取(`get()`)、移除(`remove()`)、修改(`set()`)等。此外,还有一些其他方法用于操作 ArrayList 的大小、查找元素、判断是否包含某元素等。
4. **迭代器:** ArrayList 可以通过迭代器来遍历其中的元素。迭代器提供了 `hasNext()` 和 `next()` 方法,可用于逐个访问 ArrayList 中的元素。
5. **性能考虑:** 在较大的数据集合上频繁执行插入和删除操作可能导致性能下降,因为这涉及到重新分配和复制数组元素。如果需要大量的插入和删除操作,可以考虑使用 LinkedList 或其他数据结构。
6. **与数组的相互转换:** ArrayList 可以通过 `toArray()` 方法将其转换为常规数组,也可以使用 `Arrays.asList()` 方法将常规数组转换为 ArrayList。
7. **线程安全性:** ArrayList 不是线程安全的。在并发环境下,多个线程同时修改 ArrayList 可能导致不确定的结果。如果需要在多线程环境中使用,应该考虑使用线程安全的类,如 Vector 或 CopyOnWriteArrayList。
以上是关于 ArrayList 的一些重要知识点。熟悉这些知识将有助于充分利用 ArrayList 提供的功能,并且能够选择适合实际需求的数据结构。
除此之外还涉及了接口以及覆盖的用法:
接口(Interface)和方法的覆盖(Overriding)是 Java 中面向对象编程的重要概念。以下是它们的关键知识点:
**接口(Interface):**
1. **定义和作用:** 接口是一种抽象类型,通过关键字 `interface` 定义,可以看作是一种约定或契约。它只声明了方法的签名而不提供实现细节。接口允许定义常量和抽象方法,并可被类实现。
2. **多继承:** 类只能单继承一个父类,但可以实现多个接口。通过实现接口,类可以继承多个接口定义的方法。这种机制支持Java的多继承特性,使得类可以从多个源接收功能。
3. **强制实现:** 当类实现接口时,需要提供接口中所有声明的方法的具体实现。否则,类必须声明为抽象类,交由其子类进行实现。实现接口的类必须使用关键字 `implements`。
4. **默认方法:** 从Java 8开始,接口还支持默认方法(default method),通过关键字 `default` 提供默认的方法实现。默认方法在接口中有具体的实现,但仍然可以在实现类中被覆盖。
5. **静态方法:** 从Java 8开始,接口还支持静态方法(static method),通过关键字 `static` 定义。静态方法是与接口关联的工具方法,可以直接通过接口调用。
**方法覆盖(Overriding):**
1. **定义和作用:** 方法覆盖是指子类重写父类中已有的方法的过程。当子类定义一个与父类中声明相同的方法时,子类会覆盖(重写)父类的方法实现,使得子类在运行时使用自己的方法而不是父类的方法。
2. **规则:** 方法覆盖必须满足一些规则:方法名、参数列表以及返回类型必须与父类中的方法相同;子类中的方法不能比父类中的方法具有更严格的访问修饰符;子类方法中抛出的异常不能比父类中的方法所声明的异常更多或者更通用。
3. **动态绑定:** 方法覆盖是面向对象编程中的一个重要概念,它允许程序根据实际对象类型来决定调用哪个方法。方法的调用是在运行时动态确定的,这称为动态绑定。
4. **@Override 注解:** 为了避免意外错误和提高代码可读性,可以在子类方法上使用 @Override 注解来明确表示该方法是对父类方法的覆盖。
学习和理解接口和方法覆盖的概念是进行Java面向对象编程的关键。它们提供了灵活性、可扩展性和代码组织性,使得程序更易于维护、重用和理解。
之后就是最后的课程题目了:
课程成绩统计程序-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)成绩平均分只取整数部分,小数部分丢弃
参考类图(与第一次相同,其余内容自行补充):
这里附上我的代码:
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; import java.text.Collator; import java.util.Comparator; public class Main { public static void main(String[] args) { Scanner in = new Scanner (System.in); //初始化一个Work类,开始读入数据 menu menu = new menu(); //读入数据 String message = in.nextLine(); while (!message.equals("end")){ //当message不是end的时候 menu.manage(message); //在Work类里面处理类 message = in.nextLine(); //读入下一行 } //输出学生 menu.show_Student(); //输出课程 menu.show_Course(); //输出班级 menu.show_Classroom(); } } class Student implements Comparable<Student>{ private int id; private String name; Student(int id , String name) { this.name = name; this.id = id; } @Override //学号排序 public int compareTo(Student o) { return (this.id - o.getId()); } public int getId() { return id; } public String getName() { return name; } } class Course implements Comparable<Course>{ Course(String name , String Course_Message , String Grade_Way) { this.name = name; this.Course_Message = Course_Message; this.Grade_Way = Grade_Way; } private String name; private String Course_Message; private String Grade_Way; private ArrayList<Double> Weight = new ArrayList<>(); public int compareTo(Course o) { Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA); return compare.compare(name,o.getName()); } public String getName() { return name; } public String getGrade_Way() { return Grade_Way; } public String getCourse_Message() { return Course_Message; } public void addWeight(double weight) { Weight.add(weight); } public double getWeight(int i) { return Weight.get(i); } public int get_Weight_size(){ return Weight.size(); } } class Classroom implements Comparable<Classroom>{ Classroom(int Id) { this.class_ID = Id; } private int class_ID; @Override public int compareTo(Classroom o) { return this.class_ID - o.getClass_ID(); } public int getClass_ID() { return class_ID; } } class menu { ArrayList<Student> listStudent = new ArrayList<>(); //学生表 ArrayList<Classroom> listClassroom = new ArrayList<>(); //班级表 ArrayList<Course> listCourse = new ArrayList<>(); //课程表 ArrayList<Message_Box> listMessage_Box = new ArrayList<>(); //选课记录表 InputMatching matching = new InputMatching(); public void manage(String message) { String Line[] = message.split(" " ); int j=matching.matchingInput(message); if(j==1) { //输入的是课程 Course course = new Course(Line[0],Line[1],Line[2]); if (Error_Course((course))) { //性质没有问题 if (Exist_Course(course)) {//是否存在,应该放在最后??? if (Weight_error(Line)) { //是否权重数量对不上 if (Weight_sum_error(Line)) {//是否权重数量和==1 if (Line[2].equals("实验")) { for (int i = 4; i < Line.length; i++) { course.addWeight(Double.parseDouble(Line[i])); } } else if (Line[2].equals("考试")) { course.addWeight(Double.parseDouble(Line[3])); course.addWeight(Double.parseDouble(Line[4])); } else { course.addWeight(1); } listCourse.add(course); } else { System.out.println(Line[0] + " : weight value error"); } } else { System.out.println(Line[0] + " : number of scores does not match"); } } } else { System.out.println(course.getName() + " : course type & access mode mismatch"); } } else if(j==2){ //输入的是学生 Course course = find_CourseByName(Line[2]); Student student = new Student(Integer.parseInt(Line[0]),Line[1]); Classroom classroom = new Classroom(student.getId()/100); if (Exist_Student(student)) listStudent.add(student); if (Exist_Classroom(classroom)) listClassroom.add(classroom); if (course!= null) { if (Line.length == 4) { if (course.getGrade_Way().equals("考察")){ Grade_Course grade_course = new Grade_Course(course,Line); Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else { System.out.println(Line[0] + " " + Line[1] + " : " +"access mode mismatch"); } } else { if (course.getGrade_Way().equals("考试") && Line.length == 5) { Grade_Course grade_course = new Grade_Course(course,Line); Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else if (course.getGrade_Way().equals("实验") && Line.length-3 == course.get_Weight_size()) { Grade_Course grade_course = new Grade_Course(course,Line); Message_Box messageBox = new Message_Box(student,course,grade_course); if (Exist_Message(messageBox)) listMessage_Box.add(messageBox); } else { System.out.println(Line[0] + " " + Line[1] + " : " +"access mode mismatch"); } } } else { System.out.println(Line[2] + " " + "does not exist"); } } else { System.out.println("wrong format"); } } private boolean Exist_Message(Message_Box messageBox) { for(Message_Box messageBox1 : listMessage_Box){ if ((messageBox.student.getId() == messageBox1.student.getId()) && (messageBox1.course.getName().equals(messageBox.course.getName()))){ return false; } } return true; } private boolean Exist_Classroom(Classroom classroom) { for(Classroom classroom1 : listClassroom){ if (classroom1.getClass_ID()==classroom.getClass_ID()){ return false; } } return true; } private boolean Exist_Student(Student student) { for (Student student1 : listStudent){ if (student1.getId() == student.getId()){ return false; } } return true; } private boolean Exist_Course(Course course) { for (Course course1 : listCourse){ if (course1.getName().equals(course.getName())){ return false; } } return true; } private boolean Weight_error(String[] Line) { if (Line[2].equals("实验")) { int number = Integer.parseInt(Line[3]); return Line.length - 4 == number; } else if (Line[2].equals("考试")){ return Line.length - 3 == 2; } else { return true; } } private boolean Weight_sum_error(String[] Line){ if (Line[2].equals("实验")) { double total = 0; int number = Integer.parseInt(Line[3]); for (int i = 4 ; i < number + 4 ; i++) { total += Double.parseDouble(Line[i]); } return total == 1; } else if (Line[2].equals("考试")) { double total = Double.parseDouble(Line[3]) + Double.parseDouble(Line[4]); return total == 1; } else { return true; } } private Course find_CourseByName(String name) { for (Course course : listCourse) { if (course.getName().equals((name))) { return course; } } return null; } private boolean Error_Course(Course course) { if (course.getCourse_Message().equals("必修") && course.getGrade_Way().equals("考察")){ return false; } else return (!course.getCourse_Message().equals("实验") || course.getGrade_Way().equals("实验")) && (course.getCourse_Message().equals("实验") || !course.getGrade_Way().equals("实验")); } public void show_Student() { //按学号排序 Collections.sort(listStudent); for (Student stu : listStudent) { //这里的循环是用来遍历每一位学生 //从总课表listChooseCourse中获取该学生的选课记录集合 ArrayList<Message_Box> stuCourseSelects = getStudentSelects(stu.getId()); if (stuCourseSelects.size() != 0) { System.out.println(stu.getId() + " " + stu.getName() + " " + getAvgTotalScore(stuCourseSelects)); } else { System.out.println(stu.getId() + " " + stu.getName() + " " + "did not take any exams"); } } } //获得该学生选课记录的情况下返回该学生的总成绩 private int getAvgTotalScore(ArrayList<Message_Box> stuCourseSelects) { int total = 0; for (Message_Box messageBox : stuCourseSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/stuCourseSelects.size()); } //通过学生的Id查找选课记录表,返回该学生的选课记录 private ArrayList<Message_Box> getStudentSelects(int id) { ArrayList<Message_Box> student_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.student.getId() == id) { student_Message.add(messageBox); } } return student_Message; } public void show_Course() { //按中文拼音进行排序 Collections.sort(listCourse); for (Course course : listCourse) { //这里的循环是用来遍历每一位课程 //从总选课记录listCourse中获取该课程的学生信息集合 ArrayList<Message_Box> courseStudentSelects = getcourseStudentSelects(course.getName()); if (courseStudentSelects.size() != 0) { System.out.println(course.getName() + " " + getAvgTotalCourse(courseStudentSelects)); } else { System.out.println(course.getName() + " " + "has no grades yet"); } } } private int getAvgTotalCourse(ArrayList<Message_Box> courseStudentSelects) { int total = 0; for (Message_Box messageBox : courseStudentSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/courseStudentSelects.size()); } private ArrayList<Message_Box> getcourseStudentSelects(String name) { ArrayList<Message_Box> course_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.course.getName().equals(name)) { course_Message.add(messageBox); } } return course_Message; } public void show_Classroom() { Collections.sort(listClassroom); for (Classroom classroom : listClassroom) { ArrayList<Message_Box> classroomSelects = getClassSelects(classroom.getClass_ID()); if (classroomSelects.size() != 0) { System.out.println(classroom.getClass_ID() + " " + getAvgTotalClassScore(classroomSelects)); } else { System.out.println(classroom.getClass_ID() + " " + "has no grades yet"); } } } private int getAvgTotalClassScore(ArrayList<Message_Box> classroomSelects) { int total = 0; for (Message_Box messageBox : classroomSelects) { total += messageBox.grade_course.get_grade_Total(); } return (int)(1.0*total/classroomSelects.size()); } private ArrayList<Message_Box> getClassSelects(int classId) { ArrayList<Message_Box> class_Message = new ArrayList<>(); for (Message_Box messageBox : listMessage_Box) { if (messageBox.student.getId()/100 == classId) { class_Message.add(messageBox); } } return class_Message; } class InputMatching { String Lab_Times_Matching = "[4-9]{1}"; //1个4-9的数字 String stuNumMatching = "[0-9]{8}";//8个0-9的数字 String stuNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String scoreMatching = "([1-9]?[0-9]|100)"; String courseNameMatching = "\\S{1,10}";//1到10个非空格(TAB)字符 String courseTypeMatching = "(选修|必修|实验)"; String checkCourseTypeMatching = "(考试|考察|实验)"; String rate = "^(0(\\.\\d+)?|1(\\.0+)?)$"; //courseInput用于定义课程信息模式(正则表达式) /*这里的正则表达式考虑到了长度为二的情况吗? 这里的测试测试点似乎并不考虑这给error问题*/ String courseInput_1 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching; String courseInput_2 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching + " " + rate + " " + rate; String courseInput_3 = courseNameMatching + " " + courseTypeMatching + " " + checkCourseTypeMatching + " " + Lab_Times_Matching; //scoreInput用于定义成绩信息模式(正则表达式) String scoreInput_1 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + "(scoreMatching)?"; String scoreInput_2 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " + scoreMatching + " " + scoreMatching; String scoreInput_3 = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching; public int matchingInput(String s) { String[] input = s.split(" "); String Lab_up = ""; String Lab_down = ""; if (input.length >= 4) {//防止报错 Lab_up = input[0] + " " + input[1] + " " + input[2] + " " + input[3]; Lab_down = input[0] + " " + input[1] + " " + input[2]; } if (matchingCourse(s)) {//课程之考试、考察匹配 return 1; } if (matching_Lab(Lab_up)){//课程之实验匹配 for (int i = 4 ; i < input.length ; i++) {//查看后续条件是否符合 if (!input[i].matches(rate)) {//如果找到一个不符合的 return 0; } } return 1; } if (matchingScore(s)) {//成绩之考试、考察 return 2; } if (matching_Score_Lab(Lab_down)) {//成绩之实验 for (int i = 4 ; i < input.length ; i++) {//查看后续条件是否符合 if (!input[i].matches(scoreMatching)) {//如果找到一个不符合的 return 0; } } return 2; } return 0; } private boolean matchingCourse(String s) { String[] ppp = s.split(" "); if (ppp.length==5){ if (ppp[0].matches(courseNameMatching) && ppp[1].matches(courseTypeMatching) && ppp[2].matches(checkCourseTypeMatching) && ppp[3].matches(rate) && ppp[4].matches(rate)){ return true; } } return s.matches(courseInput_1) || s.matches(courseInput_2); } private boolean matchingScore(String s) { return s.matches(scoreInput_1) || s.matches(scoreInput_2); } private boolean matching_Lab (String s) { return s.matches(courseInput_3); } private boolean matching_Score_Lab(String s) { return s.matches(scoreInput_3); } } } class Message_Box { Student student; Course course; // Grade grade; Grade_Course grade_course; Message_Box(Student student , Course course , Grade_Course grade_course) { this.student = student; this.course = course; this.grade_course = grade_course; } } class Grade_Course { ArrayList<Grade_itemize> grade_itemizes = new ArrayList<>(); Grade_Course(Course course, String[] Line) { int num = course.get_Weight_size(); if (num == 1) { grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[3]),course.getWeight(0))); } else if (num == 2) { for (int i = 0 ; i < num ; i++){ grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[i+3]),course.getWeight(i))); } } else if (num >=4 && num <=9){ for (int i = 0 ; i < num ; i++){ grade_itemizes.add(new Grade_itemize(Integer.parseInt(Line[i+3]),course.getWeight(i))); } } } public int get_grade_Total() { double total = 0; for (Grade_itemize gradeItemize : grade_itemizes) { total += gradeItemize.get_grade_One(); } return (int)Math.round(total); } } class Grade_itemize { private int score; private double date; Grade_itemize(int score , double date) { this.score = score; this.date = date; } public int getScore() { return score; } public double getDate() { return date; } public double get_grade_One() { return score*date; } }
java类中返回数值到另一个类的难点
-
类之间的关系:在Java程序设计中,类之间可以有不同的关系。要想让类A返回数值到类B,两个类之间必须要建立正确的关联,例如继承、实现接口或者依赖关系等。
-
访问权限:Java类中的方法和属性具有访问权限控制。对于要返回的数据,需要保证其访问权限得到了限定,并根据需求选择合适的访问修饰符,如private、protected、public等。
-
返回值类型和参数传递:Java中方法可以定义返回值类型和参数列表。对于要返回的数值,需要在方法的定义中正确指定返回值类型,并将需要用到的参数正确传递给方法。
-
实例化对象:将数值返回给另一个类时,还需要了解如何实例化另一个类的对象,从而能够直接使用该类的方法或属性。
-
课程一,二,三的总结:
在课程题目中,我运用了面向对象的语言去编写程序,通过书写类,对象,类中的方法,我逐步克服菜单中的难点:
1.返回值出错,由其他类返回到其他类的返回值可能因为private的缘故出错
2.书写boolean类,巧妙的运用布尔类型可以返回很多需要判断的问题以及数据
3.类方法的调用,在调用类方法的时候,或者写对象的属性的时候,经常会出错,因为写代码中总是因为自己原因写的不正规
在克服这些困难中,我不断去查代码,学习新知识,查算法,学习arraylist,huahset,hashmap,boolean或者询问别人,通过学习他人的代码,结合自己的理解,将代码不断修改完全,从不会书写类,到学习修改报错,对于idea的使用,比如调试,插件的安装与查找等技能,得到了很好的锻炼。现在可以做到以idea调试独自解决代码出现的问题,很多问题通过百度可以解决。自身解决问题能力大大提升。
在这个阶段的学习中我有以下总结:
-
学习基础知识:在学习任何编程语言之前,首先要掌握基础知识。了解Java的基本概念、语法规则、数据类型、运算符、控制流程等。可以通过阅读教材、参加培训课程或在线教育平台来学习。
-
理解面向对象编程:Java是一门面向对象的编程语言,因此理解面向对象的概念和原则是非常重要的。掌握类、对象、继承、封装、多态等概念,并能够运用它们来设计和实现程序。
-
掌握Java核心库:Java提供了丰富的核心库,包括输入输出、集合框架、多线程、异常处理等功能。学习和掌握这些核心库的使用,可以提高开发效率和代码质量。
-
实践编程:理论知识只是学习的一部分,实践是巩固和提升的关键。通过编写实际的Java程序来锻炼自己的编程能力。可以选择一些小项目或者参与开源项目,积累经验并不断提升自己的编码水平。
-
学习调试技巧:在编写程序时,难免会遇到错误和bug。学会使用调试工具和技巧,能够快速定位和解决问题。同时,学会阅读和理解错误信息,可以帮助你更好地调试程序。
-
参与社区和交流:Java拥有庞大的开发者社区,有很多优秀的论坛、博客和社交媒体群组。参与这些社区,与其他开发者交流经验和技巧,可以加快学习进度并获得更多的帮助。
-
持续学习和更新:Java是一门不断发展和更新的编程语言,新的版本和功能不断推出。要保持学习的热情,关注最新的发展动态,并不断学习和更新自己的知识。