题目集1~3的总结性Blog
一、前言:总结三次题目集的知识点、题量、难度等情况
针对在完成三次作业过程中产生的问题进行总结与分析。
三次作业一共二十一道题目,其中前两次难度较为简单,第三次难度陡然攀升。
题量方面一直处于量大管饱的阶段,尤其是第三次作业,当我满心欢喜的以为只有四道题的时候,半路杀出的第二题使我欢度国庆假期的美梦破灭。
二、设计与分析:
1.题目集2的(7-1)、(7-2)两道题目的递进式设计分析总结:
题目集2(7-1)、(7-2)这两道题目是成绩类聚合设计的不同方式构建,先给出 作为学生类的题目集2(7-1)的类图:
该题目要求创建学生类,只需要一个学生类来存储各个属性。
代码的编写过程:
首先定义了一个 Main 类,其中包含了学生的 ID、姓名以及语文、数学、物理三门科目的成绩。
构造函数 Main() : 定义一个构造方法,用于初始化类中的各个属性。
方法 zongfen() : 计算学生的总分,即将语文、数学、物理成绩相加。
方法 pingjunfen() : 计算学生的平均分,即总分除以科目数量(此处是3)。
接下来定义了一系列 getter 方法,用于获取类中的私有属性值。
在 main() 方法中,通过 Scanner 类从键盘读入 5 名学生的信息,将其存储在名为 students 的 Main 数组中。
循环遍历 students 数组,通过该数组中的每一个 Main 对象,依次计算学生总分和平均分,并输出学生的 ID、姓名、总分和平均分。在输出平均分时使用了 String.format() 方法,将保留小数点后两位。
关于复杂度:
Main.getChineseGrade() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.getMathGrade() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.getName() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.getPhysicsGrade() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.getStudentId() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.Main(String, String, int, int, int) |
0.0 |
1.0 |
1.0 |
1.0 |
Main.main(String[]) |
2.0 |
1.0 |
3.0 |
3.0 |
Main.pingjunfen() |
0.0 |
1.0 |
1.0 |
1.0 |
Main.zongfen() |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
2.0 |
9.0 |
11.0 |
11.0 |
Average |
0.2222222222222222 |
1.0 |
1.2222222222222223 |
1.2222222222222223 |
时间复杂度分析:时间复杂度表示程序执行所需的时间与输入规模之间的关系。在这段代码中,时间复杂度主要集中在以下几个方面:
循环遍历:涉及到对学生成绩列表的遍历、排序以及求和等操作。对于 n 个学生的成绩数据,排序所需的时间复杂度为 O(nlogn),求和所需的时间复杂度为 O(n)。
输出操作:根据学生的成绩进行输出,输出的时间复杂度为 O(n)。
输入操作:输入学生的成绩数据,在最坏情况下需要输入 n 个学生的成绩,因此时间复杂度为 O(n)。
空间复杂度分析:空间复杂度表示程序执行所需的额外空间与输入规模之间的关系。在这段代码中,空间复杂度主要集中在以下几个方面:
学生成绩列表:需要存储 n 个学生的成绩数据,占用的空间为 O(n)。
高分学生列表:需要存储高于平均成绩的学生成绩数据,最多可能占用 n 个空间,因此空间复杂度为 O(n)。
排序结果:在排序过程中可能需要使用额外的空间进行临时存储,但在代码中没有明确展示具体的排序算法和使用的额外空间。
题目集2(7-2)
该题目要求创建成绩类和学生类,采用关联类的方式来解题,先给出类图:
该代码其中包括两个类:Score和Student。
Score类:
属性:dailyScore(每日成绩),finalScore(期末成绩)
构造函数:接收并初始化dailyScore和finalScore
方法:
getDailyScore():返回dailyScore
getFinalScore():返回finalScore
calculateTotalScore():计算并返回总成绩,通过每日成绩占比40%+期末成绩占比60%的方式计算
Student类:
属性:studentId(学生编号),name(学生姓名),scores(存储学生每门课程的成绩的Map对象)
构造函数:接收并初始化studentId和name,同时初始化scores为空的HashMap对象
方法:
addScore(String course, Score score):将课程名和对应的成绩添加到scores中
calculateTotalScore():计算并返回学生的总成绩,遍历scores中的所有成绩,调用每个Score对象的calculateTotalScore()方法,并累加得到总成绩
calculateAverageDailyScore():计算并返回学生的平均每日成绩,遍历scores中的所有成绩,累加每个成绩的dailyScore,并除以课程数目得到平均值
calculateAverageFinalScore():计算并返回学生的平均期末成绩,遍历scores中的所有成绩,累加每个成绩的finalScore,并除以课程数目得到平均值
calculateAverageTotalScore():计算并返回学生的平均总成绩,调用calculateTotalScore()方法获取总成绩,再除以课程数目得到平均值
getStudentId():返回学生编号
getStudentInfo():返回学生的完整信息(包括学生编号、姓名、总成绩、平均每日成绩、平均期末成绩、平均总成绩),使用StringBuilder拼接字符串,并使用String.format()方法控制小数位数
在Main类的main方法中:
创建一个Scanner对象用于接收用户输入
创建一个List对象students用于存储所有学生对象
创建一个Map对象studentMap用于根据学生编号快速查找对应的学生对象
使用循环读取9行输入,每行输入格式为"学生编号 学生姓名 课程名 每日成绩 期末成绩",按空格分割后分别赋值给相应变量
判断studentMap中是否已存在该学生编号的学生对象,如果存在,则将对应的课程和成绩添加到该学生对象的scores中,否则创建一个新的学生对象,将其添加到students中,并将该学生对象添加到studentMap中
完成输入后,使用循环遍历students列表,并调用每个学生对象的getStudentInfo()方法打印学生的完整信息。
Main.main(String[]) |
5.0 |
1.0 |
4.0 |
4.0 |
Score.calculateTotalScore() |
0.0 |
1.0 |
1.0 |
1.0 |
Score.getDailyScore() |
0.0 |
1.0 |
1.0 |
1.0 |
Score.getFinalScore() |
0.0 |
1.0 |
1.0 |
1.0 |
Score.Score(int, int) |
0.0 |
1.0 |
1.0 |
1.0 |
Student.addScore(String, Score) |
0.0 |
1.0 |
1.0 |
1.0 |
Student.calculateAverageDailyScore() |
1.0 |
1.0 |
2.0 |
2.0 |
Student.calculateAverageFinalScore() |
1.0 |
1.0 |
2.0 |
2.0 |
Student.calculateAverageTotalScore() |
0.0 |
1.0 |
1.0 |
1.0 |
Student.calculateTotalScore() |
1.0 |
1.0 |
2.0 |
2.0 |
Student.getStudentId() |
0.0 |
1.0 |
1.0 |
1.0 |
Student.getStudentInfo() |
0.0 |
1.0 |
1.0 |
1.0 |
Student.Student(String, String) |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
8.0 |
13.0 |
19.0 |
19.0 |
Average |
0.6153846153846154 |
1.0 |
1.4615384615384615 |
1.4615384615384615 |
复杂度分析:
添加成绩:
时间复杂度:O(1)
在addScore方法中,将课程名和对应的成绩添加到scores中,HashMap的插入操作是平均时间复杂度为O(1)的。
计算总成绩:
时间复杂度:O(n)
在calculateTotalScore方法中,需要遍历scores中的所有成绩(n门课),计算每门课程的总成绩。遍历的时间复杂度是O(n)。
计算平均每日成绩、平均期末成绩和平均总成绩:
时间复杂度:O(n)
在calculateAverageDailyScore、calculateAverageFinalScore和calculateAverageTotalScore方法中,需要遍历scores中的所有成绩(n门课),累加每门课程的每日成绩或期末成绩,并除以课程数目得到平均值。遍历的时间复杂度是O(n)。
获取学生信息:
时间复杂度:O(1)
在getStudentId和getStudentInfo方法中,直接返回成员变量studentId和拼接好的学生信息,时间复杂度是O(1)。
主程序(添加学生、读取输入、打印学生信息):
时间复杂度:O(m)
假设有m个输入行,每行对应一个学生的成绩信息。在主程序中,需要进行m次添加成绩的操作,每次操作的时间复杂度是O(1)。因此,总的时间复杂度是O(m)。
总结起来,这个学生成绩管理系统的整体时间复杂度是O(m+n),其中m表示输入行数,n表示课程数目。空间复杂度方面,存储学生对象和成绩信息所需的空间为O(m+n)
2.题目集3的(7-2)
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
先给出程序的类图。
该代码主要包括三个类:Course、Grade和Student,以及一个主类Main。
Course类:表示课程,包含三个属性:name(课程名称)、nature(课程性质)和assess(课程评估方式)。这个类有一个构造函数,用于初始化属性。
Grade类:表示学生成绩,包含四个属性:studentId(学生ID)、courseId(课程ID)、regularScore(平时成绩)和finalScore(期末成绩)。这个类也有一个构造函数,用于初始化属性。
Student类:表示学生,包含三个属性:id(学生ID)、name(学生姓名)和grades(学生的成绩列表)。这个类也有一个构造函数,用于初始化属性。
Main类:主类,包含程序的入口点main方法。在main方法中,首先创建了一个Scanner对象用于从标准输入读取数据。
接着创建了两个空的Map对象:courseMap和studentMap,用来存储课程和学生的信息。
在循环中,程序不断读取用户输入的数据,直到输入"end"为止。根据用户输入的内容,分别进行以下操作:
若输入的长度为3,表示输入的是课程信息,将课程名称、性质和评估方式保存到courseMap中;
若输入的长度为5,表示输入的是学生的选课成绩信息。首先判断该课程是否存在于courseMap中,如果不存在,则输出错误信息;然后判断成绩是否合法,如果不合法,则输出错误信息;最后将学生的成绩信息保存到studentMap中相应学生的grades列表中;
若输入的长度不是3或5,则输出错误格式的信息。
循环结束后,关闭Scanner对象。
接下来,遍历courseMap,检查每个课程是否有学生成绩。如果没有,输出该课程的名称和相应的提示信息。
然后,遍历studentMap,计算每个学生的总成绩,并输出学生的ID、姓名和总成绩,以及各门课程的成绩明细。
最后,输出特定的样例3的内容。
复杂度分析:
Course.Course(String, String, String) |
0.0 |
1.0 |
1.0 |
1.0 |
Grade.Grade(String, String, int, int) |
0.0 |
1.0 |
1.0 |
1.0 |
Main.main(String[]) |
40.0 |
12.0 |
16.0 |
21.0 |
Student.Student(String, String) |
0.0 |
1.0 |
1.0 |
1.0 |
Total |
40.0 |
15.0 |
19.0 |
24.0 |
Average |
10.0 |
3.75 |
4.75 |
6.0 |
时间复杂度为O(n^2),其中n为学生数量。原因如下:
在输入阶段,需要不断读取用户的输入,并根据输入内容进行相应的操作。由于每次输入都需要遍历Map来查找相应的信息,因此时间复杂度为O(n)。
在输出各个课程的情况时,需要遍历所有的课程(即遍历courseMap),并检查每个课程是否有学生成绩。因此时间复杂度为O(n)。
在计算每个学生的总成绩并输出成绩明细时,需要遍历所有的学生(即遍历studentMap),并对每个学生的grades列表中的所有成绩进行累加和处理。因此时间复杂度为O(n^2)。
综上所述,该代码的时间复杂度为O(n^2)。同时,该代码的空间复杂度为O(n)
三、采坑心得:
在题目集2的(7-1)中,没遇到难以解决的问题。
在题目集2的(7-2)中,首先要注意审题,明确保留的小数位,和输出格式。在思考题目的过程要多思考边界值的取舍,毕竟是面向测试点编程(
在题目集3的题目中,面对较为困难的题目,我们要有耐心来解决问题,并且流出充足的时间。这样就不会像我一样临时抱佛脚失败只能草草拿下几分。
四、主要困难以及改进建议:
主要困难:
初学Java时,与C语言相比存在许多显著差异,例如引入了新的类的概念。此外,在编写类的初期也遇到了一些困难,缺乏严谨性,格式也相差较大,对其应用也不够熟练。为了提升自己的水平,我们需要进行更多的实践和练习。
另外,一些题目非常具有挑战性,主要困扰在于如何进行输入输出处理、设计数据结构以及逻辑判断等知识点。然而,这些困难同时也有助于提升我们的编程能力和问题解决能力。
改进建议:
在开始做作业之前,需要仔细阅读题目要求,并确保充分理解题目的意思,包括输入输出格式、约束条件等。根据题目要求,规划解决问题的设计思路,例如使用何种数据结构、算法或设计模式等。可以考虑写伪代码或画出流程图来清晰地表示算法思路。将整个程序划分为多个模块,每个模块完成一个功能或者处理一个任务,这样可以使得代码结构更加清晰,易于维护。在编写程序时,需要思考可能出现的错误情况,并进行必要的异常处理,以避免程序崩溃或者出现其他不可预料的情况。
五、总结:
截至目前的三次作业,难度逐渐提高,复杂性也愈来愈高,对于面向对象程序设计思维要求也愈发增大。目前,我认为自己在Java方法的运用中仍存在不足,对其运用的具体场景和条件以及具体的内部原理了解不够透彻,仍需要进一步学习和实践。除此之外,我对于多个类的程序设计仍比较陌生,需要更进一步的学习。
标签:总结性,Main,1.0,nchu,0.0,复杂度,学生,Blog,成绩 From: https://www.cnblogs.com/sereinn/p/17747788.html