第三次博客 pta作业总结

发布时间 2023-06-23 20:16:04作者: henrenzhenderen

(1)前言:

课程成绩统计作业知识点:

1. Java基础语法:例如变量定义、常量定义、数据类型、循环、条件语句等。             

2. 面向对象编程:例如类和对象的定义,封装、继承和多态的概念,方法的重载和重写等。 

3. 数组:因为程序上可能有多个选项,需要使用数组进行管理和操作。
4. 输入和输出:程序需要从控制台或文件中读取菜单内容,并将计算结果输出到控制台或者保存到文件中。
5. 异常处理:在程序运行过程中,可能会出现一些错误或者异常情况,需要进行捕获和处理,以保证程序正常运行且不影响用户体验。
7. 设计模式:例如观察者模式、工厂模式等设计模式可以提高代码的灵活性和可扩展性,使得程序更易于维护和修改。

难度:较困难,需要实现简单的菜单选项,实现不算复杂,只需一些基础的Java语法知识。但需要考虑到多种课程、状态切换、分数计算等场景,就需要更深入地掌握Java面向对象编程、数组、输入输出操作等相关知识。

 

(2)设计与分析:

课程统计程序知识点

思路:设计学生类,属性有学号String snum,姓名String sname,总课程平均分double p;课程类,属性有int isT课程类型(1必修,2选修,3实验),课程名称String name,课程考察方式int num(1为考试,2为考察,3为实验),每次实验的成绩权值ArrayList<Double> doubles =new ArrayList<Double>();;成绩类,属性有Student student学生类对象,Course course课程类对象,平时成绩double p,考试成绩double k;班级类,属性有String gnum班级名称,ArrayList<Student> students学生类对象集合。

创建错误信息字符串集合、输入信息字符串集合、学生类对象集合、课程类对象集合、成绩类对象集合、班级类对象集合、创建Scanner对象。使用NextLine方法进行输入。使用while循环设置为死循环进行输入每一行的数据,输入后使用equals判断是否为end,如果为end则退出循环,否则将添加后的信息添加到输入信息字符串集合中。

循环遍历输入信息集合字符串集合,对其中每一个信息都使用split方法进行分割成字符串数组。使用if-elseif选择结构进行分别处理数据,判断条件为字符串数组第一个元素是否为数字,是数字的就是学号是成绩信息,不是数字的话就是课程信息处理。

课程信息处理,根据课程的类型进行分别处理,是考察则直接校验,是考试则需要把考试权重和平时权重添加到对象的权重集合中,是实验就将每次的权重添加到对象权重集合中,根据输入的信息,生成对应的课程类对象,设定好对应的值,处理完成后添加进课程类对象集合中,校验不符合就使用continue退出该次循环进行下一次。

成绩信息处理,分为数组长度为4、数组长度为5还有长度大于5的进行处理,长度为4的是考察只有平时成绩,长度为5的是考试有这考试成绩和平时成绩,考试要遍历课程对象的权重集合然后将其对应乘出成绩添加到p和k上,长度大于5的是实验的成绩,在成绩处理的时候直接将其根据要求遍历课程的权重然后乘出成绩然后添加到p上,进行校验后添加到成绩类对象集合中,校验不符合就使用continue退出该次循环进行下一次。

循环遍历学生类对象集合和班级类对象集合,使用冒泡排序进行处理,使得符合要求;遍历课程类对象集合,将其课程名都加入到一个数组中,然后创建一个Comparator对象,Comparator comp = Collator.getInstance(java.util.Locale.CHINESE);根据中文字符循序进行排序,然后在遍历整个数据将对应的课程对象添加到一个新的集合中。

遍历输出排序后的学生类对象集合、课程类对象集合、班级类对象集合,按要求进行计算和输出对应的信息。

 

类图:

 

 

 

圈复杂度

 

 

 

 

源码:

import java.text.Collator;
import java.util.*;
import java.util.regex.Pattern;

class Course {
String name;
String type; //必修 选修
String mode; //考试 考核
boolean st;

public Course(String name, String type, String mode) {
this.name = name;
this.type = type;
this.mode = mode;
st = false;
}

public Course() {
st = true;
}
}

class Student {
String id;
String name;
String classId;

public Student(String id, String name) {
this.id = id;
this.name = name;
this.classId = id.substring(0, 6);
}
}

class Score {
Course course;
Student student;
String classId;
int ordinarily;
int finalExam;

public Score(Course course, Student student, String classId, int finalExam) {
this.course = course;
this.student = student;
this.classId = classId;
this.finalExam = finalExam;
}

public Score(Course course, Student student, String classId, int ordinarily, int finalExam) {
this.course = course;
this.student = student;
this.classId = classId;
this.ordinarily = ordinarily;
this.finalExam = finalExam;
}
}

public class Main {

public static boolean isNumeric(String str) {
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}


public static boolean isNumeric2(String str) {
for (int i = 0; i < str.length(); i++) {
int chr = str.charAt(i);
if (chr < 48 || chr > 57)
return false;
}
return true;
}


public static void main(String[] args) {

Collator collator = Collator.getInstance(Locale.CHINA);

Scanner cin = new Scanner(System.in);
TreeMap<String, Course> courseHashMap = new TreeMap<>(collator);
TreeSet<String> studentSet = new TreeSet<>();

TreeSet<String> re = new TreeSet<>();

TreeSet<String> classSet = new TreeSet<>();

TreeSet<String> scoreSet = new TreeSet<>();

TreeMap<String, ArrayList<Score>> student2ScoreHashMap = new TreeMap<>();
TreeMap<String, ArrayList<Score>> course2ScoreHashMap = new TreeMap<>();
TreeMap<String, ArrayList<Score>> class2ScoreHashMap = new TreeMap<>();

while (true) {
String str = cin.nextLine();
if (Objects.equals(str, "end")) {
break;
}
String[] split = str.split(" ");
if (split.length <= 1 || split.length > 5) {
System.out.println("wrong format");
}
else if (split.length <= 3) { //课程
if (courseHashMap.containsKey(split[0])) {
continue;
}

if (split[0].length() > 10) {
System.out.println("wrong format");
continue;
}
if (!(Objects.equals(split[1], "必修") || Objects.equals(split[1], "选修"))) {
System.out.println("wrong format");
continue;
}

if (split.length == 3 && !(Objects.equals(split[2], "考察") || Objects.equals(split[2], "考试"))) {
System.out.println("wrong format");
continue;
}

if (split.length == 2) {
if (Objects.equals(split[1], "选修")) {
System.out.println(split[0] + " : course type & access mode mismatch");
courseHashMap.put(split[0], new Course());
continue;
}
Course course = new Course(split[0], split[1], "考试");
courseHashMap.put(split[0], course);
}
else if (split.length == 3) {
if (Objects.equals(split[1], "必修") && Objects.equals(split[2], "考察")) {
System.out.println(split[0] + " : course type & access mode mismatch");
courseHashMap.put(split[0], new Course());
continue;
}
Course course = new Course(split[0], split[1], split[2]);
courseHashMap.put(split[0], course);
}
}
else {
if (split.length == 4) {
//学号、姓名、课程名称、期末成绩
if (split[0].length() != 8 || split[1].length() > 10 || split[2].length() > 10) {
System.out.println("wrong format");
continue;
}

if (!isNumeric2(split[0])) {
System.out.println("wrong format");
continue;
}

if (!isNumeric(split[3])) {
System.out.println("wrong format");
continue;
}
int mark = Integer.parseInt(split[3]);
if (mark < 0 || mark > 100) {
System.out.println("wrong format");
continue;
}

boolean verify = true;
if (!courseHashMap.containsKey(split[2])) {
System.out.println(split[2] + " does not exist");
verify = false;
}

Course course = courseHashMap.get(split[2]);

if (verify && (course==null || course.st)) {
System.out.println(split[2] + " does not exist");
verify = false;
}

if (verify && Objects.equals(course.mode, "考试")) {
System.out.println(split[0] + " " + split[1] + " : access mode mismatch");
verify = false;
}

if (scoreSet.contains(split[0] + " " + split[2])) {
continue;
}

Student student = new Student(split[0], split[1]);
String classId = student.classId;
Score score = new Score(course, student, classId, mark);

studentSet.add(split[0] + " " + split[1]);
classSet.add(classId);


if (!verify) {
continue;
}

scoreSet.add(split[0] + " " + split[2]);

ArrayList<Score> list1;
if (!student2ScoreHashMap.containsKey(student.id)) {
list1 = new ArrayList<>();
}
else {
list1 = student2ScoreHashMap.get(student.id);
}
list1.add(score);
student2ScoreHashMap.put(student.id, list1);

ArrayList<Score> list2;
if (!course2ScoreHashMap.containsKey(course.name)) {
list2 = new ArrayList<>();
}
else {
list2 = course2ScoreHashMap.get(course.name);
}
list2.add(score);
course2ScoreHashMap.put(course.name, list2);

ArrayList<Score> list3;
if (!class2ScoreHashMap.containsKey(classId)) {
list3 = new ArrayList<>();
}
else {
list3 = class2ScoreHashMap.get(classId);
}
list3.add(score);
class2ScoreHashMap.put(classId, list3);
}
else if (split.length == 5) {
//学号、姓名、课程名称、平时成绩、期末成绩

if (split[0].length() != 8 || split[1].length() > 10 || split[2].length() > 10) {
System.out.println("wrong format");
continue;
}

if (!isNumeric2(split[0])) {
System.out.println("wrong format");
continue;
}

if (!isNumeric(split[3])) {
System.out.println("wrong format");
continue;
}

int ordinarilyMark = Integer.parseInt(split[3]);

if (ordinarilyMark < 0 || ordinarilyMark > 100) {
System.out.println("wrong format");
continue;
}

if (!isNumeric(split[4])) {
System.out.println("wrong format");
continue;
}

int finalMark = Integer.parseInt(split[4]);
if (finalMark < 0 || finalMark > 100) {
System.out.println("wrong format");
continue;
}

boolean verify = true;
if (!courseHashMap.containsKey(split[2])) {
System.out.println(split[2] + " does not exist");
verify = false;
}

 


Course course = courseHashMap.get(split[2]);

if (verify && (course==null || course.st)) {
System.out.println(split[2] + " does not exist");
verify = false;
}

if (verify && Objects.equals(course.mode, "考察")) {
System.out.println(split[0] + " " + split[1] + " : access mode mismatch");
verify = false;
}

if (scoreSet.contains(split[0] + " " + split[2])) {
continue;
}


Student student = new Student(split[0], split[1]);
String classId = student.classId;
Score score = new Score(course, student, classId, ordinarilyMark, finalMark);


studentSet.add(split[0] + " " + split[1]);
classSet.add(classId);

if (!verify) {
continue;
}
scoreSet.add(split[0] + " " + split[2]);
ArrayList<Score> list1;
if (!student2ScoreHashMap.containsKey(student.id)) {
list1 = new ArrayList<>();
}
else {
list1 = student2ScoreHashMap.get(student.id);
}
list1.add(score);
student2ScoreHashMap.put(student.id, list1);

ArrayList<Score> list2;
if (!course2ScoreHashMap.containsKey(course.name)) {
list2 = new ArrayList<>();
}
else {
list2 = course2ScoreHashMap.get(course.name);
}
list2.add(score);
course2ScoreHashMap.put(course.name, list2);

ArrayList<Score> list3;
if (!class2ScoreHashMap.containsKey(classId)) {
list3 = new ArrayList<>();
}
else {
list3 = class2ScoreHashMap.get(classId);
}
list3.add(score);
class2ScoreHashMap.put(classId, list3);
}
}
}

for (String s : studentSet) {
String id = s.split(" ")[0];
if (!student2ScoreHashMap.containsKey(id)) {
System.out.println(s + " did not take any exams");
}
else {
ArrayList<Score> list = student2ScoreHashMap.get(id);
int len = list.size();
long ordMarks = 0;
long finalMarks = 0;
long marks = 0;
for (Score score : list) {
if (Objects.equals(score.course.mode, "考试")) {
ordMarks += score.ordinarily;
finalMarks += score.finalExam;
}
else {
marks += score.finalExam;
}
}
double gpa = ordMarks * 0.3 + finalMarks * 0.7 + marks;
System.out.println(s + " " + (long) (gpa / len));
}
}

for (String s : courseHashMap.keySet()) {
Course course = courseHashMap.get(s);
if (course.st) {
continue;
}
if (!course2ScoreHashMap.containsKey(s)) {
System.out.println(s + " has no grades yet");
}
else {
ArrayList<Score> list = course2ScoreHashMap.get(s);
int len = list.size();
if (Objects.equals(course.mode, "考试")) {
long ordMarks = 0;
long finalMarks = 0;
for (Score score : list) {
ordMarks += score.ordinarily;
finalMarks += score.finalExam;
}
double gpa = ordMarks * 0.3 + finalMarks * 0.7;
System.out.println(s + " " + (ordMarks / len) + " " + (finalMarks / len) + " " + (long) (gpa / len));
}
else {
long finalMarks = 0;
for (Score score : list) {
finalMarks += score.finalExam;
}
System.out.println(s + " " + (finalMarks / len) + " " + (finalMarks / len));
}
}
}

for (String s : classSet) {
if (!class2ScoreHashMap.containsKey(s)) {
System.out.println(s + " has no grades yet");
}
else {
ArrayList<Score> list = class2ScoreHashMap.get(s);
int len = list.size();
long ordMarks = 0;
long finalMarks = 0;
long marks = 0;
for (Score score : list) {
if (Objects.equals(score.course.mode, "考试")) {
ordMarks += score.ordinarily;
finalMarks += score.finalExam;
}
else {
marks += score.finalExam;
}
}
double gpa = ordMarks * 0.3 + finalMarks * 0.7 + marks;
System.out.println(s + " " + (long) (gpa / len));
}
}
}
}

 

 

 

知识点讲解:

  1. 在实现长度质量计量单位换算程序时,需要使用到Java中的基本数据类型、运算符和控制语句等知识。我们需要定义一些变量来保存输入数据,并使用条件语句处理异常情况,例如用户输入非法字符等。

    2. 面向对象编程思想
    为了实现程序的可重用性和扩展性,可以采用面向对象编程思想。可以将程序拆分为多个类,每个类负责不同的功能模块。例如,在程序中可以定义一个名为Converte r的类来进行单位转换操作。

Menu类表示一个菜单项,在这里定义了菜名、价格等属性,并提供相关get/set方法。
Order类表示一个订单项,在这里定义了所点菜名及份数等属性,并提供相关get/set方法以及计算总金额的方法。
Main类为主函数入口,负责控制整个逻辑流程,并与用户进行交互

代码实现分析:
在代码实现方面,该程序结构清晰,注释详细,优化良好。在Menu和Order两个类中使用了封装性原则,并且应用了面向对象编程中的继承和重载等特性。同时,在Main函数中也用到了异常处理机制,增强了程序的健壮性。

(3):踩坑心得

1. 编译错误:PTA上的题目往往需要使用Java的类库,如果没有正确导入这些类库,就会出现编译错误。在做题之前,要先阅读题目中所提到的类库,并将其导入到代码中。

2. 输入输出问题:PTA平台会提供多组测试数据,所以要注意输入输出格式。在处理输入时,应该使用Scanner或BufferedReader等工具类;在输出时,应该注意格式控制。

3. 数组越界错误:数组越界错误是一个常见的运行时错误。要避免这个错误,可以使用for-each循环或者List等Java集合代替原生数组。

4. 逻辑错误:有些PTA题目需要考虑边界和特殊情况。在编写代码之前,要认真阅读题目并理解需求,在代码实现过程中考虑各种可能性,并对每个分支进行测试。

5. 在使用Scanner类获取用户输入时,要注意避免空格、回车等非数字字符的干扰。可以在获取完数字后使用nextLine()方法将其余字符清空。

6. 在使用switch语句实现菜单功能时,要注意case语句中的break语句的位置。如果break放在末尾,则会出现意外的bug。建议将break放在case逻辑块的最后一行。


7. 菜单价格计算可能会产生小数,需要考虑数据类型和精度问题。可以使用BigDecimal类进行高精度运算。


8. 如果菜单计价程序中菜单很长,代码可读性和维护性都会降低。可以将菜单选项封装成一个独立类或枚举类型,并提供相应的方法。

(4):主要困难及改进意见

  1. 困难:理解题目要求和建立问题模型是解题的关键。对于一些复杂的问题,在理解要求和建立模型过程中可能会出现困难。

    改进建议:在遇到难题时,不要放弃,应该经常深入思考和讨论,并尝试寻找更多的资料和范例来帮助理解。多看老师课上讲授的相关知识点,加强对基本操作的掌握,逐步积累编程思维能力。

    2. 困难:编码中出现了语法错误或逻辑错误,导致程序无法正常运行或得到正确结果。

    改进建议:细心地阅读代码、Debug技巧、注释技巧都非常重要。需要用心去分析每一个代码片段,并且有时需要进行代码重构或抽象化以优化代码。在遇到问题时,可以通过查看错误信息、调试语句等方式找到错误并修正它们。

    3. 困难:时间限制过短或作业质量过高,导致完成作业较为困难。

    改进建议:将时间合理分配并进行有效使用,放弃一开始就想从头到尾完成作业的想法。在时间不够的情况下,优先解决高分值的问题。同时,要阅读题目和代码,在理解后再进行编码。可以把一道大题拆成若干小题进行处理,逐渐深入理解问题。

(5):总结

1.

通过本阶段三次题目集,我学到了Java基础知识的运用,如循环结构、条件语句、数组、方法等。同时也学习到了面向对象编程的概念和实现,如封装、继承和多态等。

在完成菜单计价程序时,我深入了解了Java中Scanner类和DecimalFormat类的使用。使用Scanner获取用户输入,并通过DecimalFormat类对输出结果进行格式化,达到更好的视觉效果。

在实践过程中,我也发现了自己的不足之处。比如对Java集合类的掌握还不够熟练,在程序设计中往往使用基础数据类型进行处理,而没有充分利用Java提供的集合类及其相关方法。因此,在日后需要进一步学习并熟悉Java集合类的应用。

此外,在代码设计过程中还需要注意模块化思想,即将大问题拆分为小问题进行解决,并考虑代码重复利用率和可维护性等因素。

总之,通过这三次题目集的实践,我深入理解了Java编程语言,并掌握了一些基础开发技能。在未来的学习与实践中,我将进一步加强自身技能储备,并努力优化代码设计与开发效率。

2.

下面是我对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。


1. 教师方面:建议教师讲解时能够结合实际应用场景进行讲解,提高学生的兴趣。同时,在授课内容方面,建议加强对一些实践性较强的内容进行解释和演示。

2. 课程方面:建议在Java语言相关知识点学习之外,可以增加一些实际项目案例进行讲解,并介绍相关行业知识,有助于学生更好地了解该领域的发展趋势和应用场景。

3. 作业方面:建议定期布置合理难度的编程作业,并严格按时同步批阅,及时反馈学生问题并提供优质批改意见。

4. 实验方面:建议设计具有一定难度和挑战性的实验题目,并在实验过程中能够引导学生思考问题并正确使用Java语言进行解决。

5. 课上及课下组织方式方面:针对Java课程特点,可以增加小组讨论、团队作业等课下学习方式,以及线上分享、线下实践等更多的课上教学方式,并鼓励学生积极参与,促进互动交流。同时,建议有关部门加强Java课程授课质量监管和教师培训,确保Java课程能够得到有效推广和应用。

改进:

1.勤于练习,不能只看这一次的作业,自己也要从别的方向吸收知识和习题,菜单的程序尽量写到满分。

2.充分利用时间,主动积极学习,对上课和自学的知识反复琢磨。

3.反复理解作业,将作业中的重点知识理解清楚。

4.上课认真听讲充分理解,课堂作业能写还是积极交作业。

期待:随着题目越来越难,希望有时间自己多加练习,能够避免一些本不该出现的愚蠢问题,

多利用碎片化时间进行学习,拒绝摆烂。


希望以上意见可以对Java课程的改进建设有所启发。