nchu题目集1~3的总结性Blog

发布时间 2023-10-07 23:40:57作者: 太白丶

题目集1~3的总结性Blog

 

一、前言:总结三次题目集的知识点、题量、难度等情况

 

 

针对在完成三次作业过程中产生的问题进行总结与分析。

三次作业一共二十一道题目,其中前两次难度较为简单,第三次难度陡然攀升。

题量方面一直处于量大管饱的阶段,尤其是第三次作业,当我满心欢喜的以为只有四道题的时候,半路杀出的第二题使我欢度国庆假期的美梦破灭。

 

 

 

 

 

二、设计与分析:

 1.题目集2的7-1)、(7-2)两道题目的递进式设计分析总结:

 

 题目集27-1)、(7-2)这两道题目是成绩类聚合设计的不同方式构建,先给出 作为学生类的题目集27-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)。

排序结果:在排序过程中可能需要使用额外的空间进行临时存储,但在代码中没有明确展示具体的排序算法和使用的额外空间。

 

题目集27-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方法的运用中仍存在不足,对其运用的具体场景和条件以及具体的内部原理了解不够透彻,仍需要进一步学习和实践。除此之外,我对于多个类的程序设计仍比较陌生,需要更进一步的学习。