6-8次PTA题目总结
1,前言
第6-8次的PTA题目集主要便是完成课程成绩统计程序的一系列编写及实现,其次便是学习ArrayList集合及HashMap集合的使用及运用,最后则是复习及训练了接口,多态,及继承相关的知识,并加以练习。
2,设计与分析
课程成绩统计程序-1类图

第一次的课程成绩统计程序较为直观,题目要求中直接给了相关的类图,以及需要构造的相关类,在按照土题目的相关要求即可较为完整的实现成绩统计的功能,在本次课程统计的编写中运用ArrayList以及正则表达式即可克服相关难点,实现相关功能。
课程成绩统计程序-2类图

课程成绩统计程序-3类图

3,踩坑心得
源码:
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Arithmetic arithmetic = new Arithmetic();
Scanner sc = new Scanner(System.in);
String record = sc.nextLine();
Grade grade = new Grade();
while (true) {
if (record.matches("[\\S]{0,11} [\\S]+ [\\S]+")) {
String[] token = record.split(" ");
if (!(token[1].equals("必修") || token[1].equals("选修"))) {
System.out.println("wrong format");
record = sc.nextLine();
continue;
}
if (!((token[2]).equals("考试") || token[2].equals("考察"))) {
System.out.println("wrong format");
record = sc.nextLine();
continue;
}
if (arithmetic.searchCourse(token[0]) != -1) {
record = sc.nextLine();
continue;
}
arithmetic.analysisACourse(token[0], token[1], token[2]);
record = sc.nextLine();
} else if (record.matches("[\\d]{8} [\\S]{0,10} [\\S]{0,10} [0-9]{1,4}[\\s]?[0-9]{0,3}")) {
break;
} else if (record.equals("end")) {
break;
} else {
System.out.println("wrong format");
record = sc.nextLine();
}
}
while (true) {
if (record.matches("[\\d]{8} [\\S]{0,10} [\\S]{0,10} [0-9][\\d]?[0]?") || record.matches("[\\d]{8} [\\S]{0,10} [\\S]{0,10} [0-9][\\d]?[0]? [0-9][\\d]?[0]?")) {
String[] token = record.split(" ");
String classNum = token[0].substring(0, 6);
int classNumByGrade = grade.searchClass(classNum);
if (classNumByGrade == -1) {
grade.addAClass(classNum);
grade.classes.get(grade.classes.size() - 1).addAStudent(token, arithmetic);
} else {
int studentNum = grade.classes.get(classNumByGrade).searchAStudent(token[0]);
if (studentNum == -1) {
grade.classes.get(classNumByGrade).addAStudent(token, arithmetic);
} else {
grade.classes.get(classNumByGrade).addACourse(studentNum, token, arithmetic);
}
}
record = sc.nextLine();
} else if (record.equals("end")) {
break;
} else {
System.out.println("wrong format");
record = sc.nextLine();
}
}
grade.showStudentsGrades();
grade.getSum();
arithmetic.getEndGrade();
arithmetic.showEndGrades();
grade.showClassGrades();
}
}
class Course {
String name;
String nature;
String way;
int pacific_grade;
int final_Grade;
int end_grade;
int gradeNum = 0;
public Course(String name, String nature, String way) {
this.name = name;
this.nature = nature;
this.way = way;
}
public void getEndGrade() {
if (gradeNum == 0) {
return;
}
pacific_grade = (int) Math.floor(pacific_grade / gradeNum);
final_Grade = (int) Math.floor(final_Grade / gradeNum);
if (way.equals("考察")) {
end_grade = final_Grade;
} else {
end_grade = (int) Math.floor(pacific_grade * 0.3 + final_Grade * 0.7);
}
}
public void showEndGrade() {
if (end_grade == 0) {
System.out.println(name + " has no grades yet");
} else {
if (way.equals("考察")) {
System.out.println(name + " " + final_Grade + " " + end_grade);
} else {
System.out.println(name + " " + pacific_grade + " " + final_Grade + " " + end_grade);
}
}
}
}
class Arithmetic {
ArrayList<Course> courses = new ArrayList<>();
public void analysisACourse(String name, String nature, String way) {
if (nature.equals("必修") && way.equals("考察")) {
System.out.println(name + " : course type & access mode mismatch");
return;
}
courses.add(new Course(name, nature, way));
}
public int searchCourse(String name) {
for (int i = 0; i < courses.size(); i++) {
if (courses.get(i).name.equals(name)) {
return i;
}
}
return -1;
}
public void getEndGrade() {
for (int i = 0; i < courses.size(); i++) {
courses.get(i).getEndGrade();
}
}
public void showEndGrades() {
courses.sort((o1, o2) -> {
Collator collator = Collator.getInstance(java.util.Locale.CHINA);
return collator.compare(o1.name, o2.name);
});
for (int i = 0; i < courses.size(); i++) {
courses.get(i).showEndGrade();
}
}
}
class Student {
String ID;
String name;
int pacific_grade;
int final_grade;
int sum_grade = 0;
Course chooseCourse;
ArrayList<String> courses = new ArrayList<>();
int choose = 0;
public void getSumGrade() {
if (chooseCourse == null) {
sum_grade = 0;
} else {
if (chooseCourse.way.equals("考察")) {
sum_grade += final_grade;
} else {
sum_grade += Math.floor(pacific_grade * 0.3 + final_grade * 0.7);
}
pacific_grade = 0;
final_grade = 0;
chooseCourse = null;
}
}
public void showAverageGrade() {
if (choose != 0) {
sum_grade /= choose;
}
if (sum_grade == 0) {
System.out.println(ID + " " + name + " " + "did not take any exams");
} else {
System.out.println(ID + " " + name + " " + sum_grade);
}
}
public void searchACourse(String[] token, Arithmetic arithmetic) {
if (arithmetic.searchCourse(token[2]) == -1) {
System.out.println(token[2] + " does not exist");
return;
}
Course course = arithmetic.courses.get(arithmetic.searchCourse(token[2]));
chooseCourse = course;
if (course.way.equals("考察") && token.length > 4 || (course.way.equals("考试") && token.length < 5)) {
System.out.println(ID + " " + name + " " + ": access mode mismatch");
return;
}
if (chooseCourse.way.equals("考察")) {
if (Integer.parseInt(token[3]) > 100) {
System.out.println("wrong format");
return;
}
final_grade = Integer.parseInt(token[3]);
course.final_Grade += Integer.parseInt(token[3]);
} else {
if (Integer.parseInt(token[3]) > 100 || Integer.parseInt(token[4]) > 100) {
System.out.println("wrong format");
return;
}
pacific_grade = Integer.parseInt(token[3]);
course.pacific_grade += Integer.parseInt(token[3]);
final_grade = Integer.parseInt(token[4]);
course.final_Grade += Integer.parseInt(token[4]);
}
course.gradeNum++;
choose++;
courses.add(token[2]);
getSumGrade();
}
public boolean judge(String course) {
return courses.contains(course);
}
}
class Class {
String classNum;
ArrayList<Student> students = new ArrayList<>();
int studentNum = 0;
int averageGrade = 0;
public void addAStudent(String[] token, Arithmetic arithmetic) {
Student temp = new Student();
temp.ID = token[0];
temp.name = token[1];
temp.searchACourse(token, arithmetic);
students.add(temp);
}
public int searchAStudent(String ID) {
for (int i = 0; i < students.size(); i++) {
if (students.get(i).ID.equals(ID)) {
return i;
}
}
return -1;
}
public void addACourse(int i, String[] token, Arithmetic arithmetic) {
Student temp = students.get(i);
if (temp.judge(token[2])) {
return;
}
temp.searchACourse(token, arithmetic);
}
public void getSum() {
for (int i = 0; i < students.size(); i++) {
averageGrade += students.get(i).sum_grade;
if (students.get(i).sum_grade != 0) {
studentNum++;
}
if (studentNum != 0) {
averageGrade /= studentNum;
}
}
}
public void showStudentGrade() {
students.sort(Comparator.comparing(o -> o.ID));
for (int i = 0; i < students.size(); i++) {
students.get(i).showAverageGrade();
}
}
public void showClassGrade() {
if (averageGrade == 0) {
System.out.println(classNum + " has not grades yet");
} else {
System.out.println(classNum + " " + averageGrade);
}
}
}
class Grade {
ArrayList<Class> classes = new ArrayList<>();
public int searchClass(String classNum) {
for (int i = 0; i < classes.size(); i++) {
if (classes.get(i).classNum.equals(classNum)) {
return i;
}
}
return -1;
}
public void addAClass(String classNum) {
Class temp = new Class();
temp.classNum = classNum;
classes.add(temp);
}
public void getSum() {
for (int i = 0; i < classes.size(); i++) {
classes.get(i).getSum();
}
}
public void showStudentsGrades() {
classes.sort(Comparator.comparing(o -> o.classNum));
for (int i = 0; i < classes.size(); i++) {
classes.get(i).showStudentGrade();
}
}
public void showClassGrades() {
classes.sort(Comparator.comparing(o -> o.classNum));
for (int i = 0; i < classes.size(); i++) {
classes.get(i).showClassGrade();
}
}
}
java 选修 考察
20201103 李四 java 60
20201104 王五 java 60
20201101 张三 java 40
end
20201101 张三 40
20201103 李四 60
20201104 王五 60
java 53 53
202011 36
进程已结束,退出代码0
最先我尝试过对每个格式采取逐个相等的方法,过程相当麻烦,最后甚至超过了PTA的最大限度,并且在写完代码后,测试点确实是能过,但是格式错误无法从根本上解决,既然给出最大限度并出了题目,就说明有更简洁的方法可以完成相应的工作,在使用正则表达式后代码明显简洁了许多,并且解决了格式错误的问题;
首先我尝试的时在类里创建另外类的链表,在格式正确的情况下添加进链表中,我个人认为还是比较符合面向对象的思想,最后还是有些测试点解决不了,改进了几次,最后方案为,先进行格式判断,正确之后无论对错都添加进链表中,再经过一系列方法的筛选,最后打印出结果;
改进建议
可以将Score改成抽象类,代码量太大了,后续再添加成绩类型时可能会忘记一些方法,改成抽象类可以在编写时,不需要太注意分数的计算方法,在一定程度上帮助编写代码的实用性;
总结
本次作业,我个人进步最大的地方是学习了几个设计模式来辅助自己设计,这让我代码整体结构比较好,思路清晰,逻辑严谨。这次作业我也学到了多线程编程的基本方法;
本次实验中第一次接触了正则表达式,也体会到了正则表达式的强大,正则的效率挺高的,在很多情况下都能用到,对正则表达式更加熟练了;
但是,我还有许多地方有待进步,比如测试环节。设计模式也需要抓紧时间学习。
浙公网安备 33010602011771号