题目集1~3的总结
一、前言
1.由于是第一次写博客,难免有点生疏,所以请读者见谅,不过确实不会被其他人看到。首先,就是之前学的是C语言,是面向过程的一个编程高级语言。这些题目都是面对对象的,并且在题目中也会设计类,那么给出属性还有方法让我们实现。涉及到类和对象的使用,类、数组的基本运用和关联类等的使用。然后就是面向对象的编程需要封装类,一个类的属性和方法就应该封装好。对于一个Main类中应该就只有一个main方法,其他方法要在其他类中。相对于C语言来说,Java语言在实现上可能会麻烦一点,但是对于后面的复用性很高。比如一个学生类,在一个地方可以使用,当在另一个地方使用时,还可以把之前写的拿过来用。对于public的使用来说,我都是一个文件的,那么只有一个Main类会在前面加上public,如果在其他类前面加上public的话会报错。一个类里面的属性一般都要加上private。对于方法来说一般一个属性都要有一个SET和GET,有时确实用不到。还涉及到了数据结构中数组,列表的使用。还有模块化设计,类的职责分离,每个类负责不同的功能。
2.对于题目量来说,题目并不是很多,但是难度上就很高。题目是从第一个开始,慢慢往里面又加了一些东西,所以也是越来越难。比如最后一个题目集的最后一题就是很多测试是测试代码的健壮性,题目比较困难。题目都是输入输出格式给出的,那么需要仔细看。但是一些特殊情况就非常需要注意,因为这些特殊情况很有可能在测试中出现。测试点是很多的,但是一般通过的测试点很少。
二、设计与分析
第一次作业
类图:
耦合度
第一次作业的输入和输出都比较简单,题目中也提示了需要使用题目类,试卷类和答卷类。那么要建立这些类,还加了分离问题和分离答案的类。这里是第一次用到了正则表达式,确实有点吃力。
当处理到“end”时,就结束输入。第一次这个作业答题判题程序还是比较简单的,因为自己第一次接触这么多代码量的题目才比较花时间。简单说明代码就是从标准输入读取题目数量、题目信息和答案信息。解析输入信息,生成题目和答案对象。输出题目的内容和对应答案。判断答案是否正确,并输出判断结果。
第二次作业
类图
耦合度
第二次作业沿用了上一次作业的题目类,试卷类和答卷类,还相应的增加了题目集类,试卷集类还有答卷集类,另外因为这个题目有分数。所以在这次代码里面还增加了一个题目分数类,用于处理分数。
这次作业的测试点就比较多的问题了,那么我还是比较困难的一个一个的解决了。并且这次作业我将Main类和main方法里面的内容给减少了,我是用减少这个词,不知道正确的词是什么。把一些输入和输出放到了其他类里面,所以看上去我的Main类没有几行代码。
第三次作业
类图
耦合度
顺序图画的有点不太对,因为对顺序图不是十分了解。后面还要继续加强学习。
耦合度也还不知道看什么不过确实很多时候在移除一些类以后能够正常工作也说明了耦合度较低。类图与顺序图还要多学习才能比较准确的画出来。其实也就是输入,然后处理输入,最后输出,都是这样的思路。第三次作业是没有完全写成,只是对了几个测试点。这次作业的类与上次的基本一样,只是多了一个学生类,那么在一些类上也要加上。答卷类里面要加上一个学生学号的属性。这次作业比之前的作业都难,而且还会检查代码的健壮性。只要没有考虑周全很可能就错太多。大概有这些,Topic类,用于表示题目。包含题目编号id、题目内容content、题目答案answer和题目类型type四个属性。通过构造函数接收这四个属性的值进行初始化。Paper类代表试卷,包含试卷编号id和一个Map类型的属性questions,用于存储题目编号和对应的题目分值。
提供方法addQuestion用于向试卷中添加题目及其分值,totalScore方法用于计算试卷的总分。Student类,表示学生。有学生编号id和学生姓名name两个属性,通过构造函数进行初始化。Answer类,用于存储学生的答题信息。包含试卷编号paperId、学生编号studentId和一个Map类型的属性answers,用于存储题目在试卷中的索引和对应的学生答案。addAnswer方法用于向答题信息中添加题目答案。Topicnumandfs类作为数据存储类,用于存储题目、试卷、学生和答题信息等数据。包含Map类型的questions用于存储题目对象、Map类型的papers用于存储试卷对象、Map类型的students用于存储学生对象、List类型的answers用于存储答题对象以及Set类型的deletedQuestions用于存储已删除的题目编号。提供一系列方法用于添加题目、试卷、学生和答题信息,以及删除题目和获取各种数据的方法。
三、踩坑心得
第一次作业
第一次作业的错误比较少,但是还是有一些问题的。比如说,当一个输入的空格有点多时,代码就不能正确处理了。那么我就加入了处理空格的方法,还好正确完成了。正确处理完成以后其他基本一下子就是通过了。
第二次作业
1.第二次作业的难度就增加了,一下子错了很多。虽然是正常的因为很多时候没有考虑全面,只是考虑了几个甚至只是考虑了一个最简单的输入输出。
2.基本上只能处理最简单的样例。然后我出现了一个格式错误。
public void processAnswers(TopicBank topicBank, TestPapers testPapers, AnswerSheets answerSheets) {
int score;
int scoreAll;
List
for (TestPaper testPaper : testPapers.getList()) {
scoreAll = 0;
for (TopicNumAndScore topicInfo : testPaper.getList()) {
scoreAll += topicInfo.getScore();
}
if (scoreAll != 100) {
System.out.println("alert: full score of test paper " + testPaper.getPaperNum() + " is not 100 points");
}
}
3.只是一部分代码,然后感觉也没有什么问题。但是又去测试一下,分析到paper后面多了一个空格,就是一个十分简单的格式错误。删去这个空格以后,就能够正确处理一些测试了。
后面又有一个是格式错误。
4.基于上次的经验,我觉得又是哪里少了一个空格或者多了一个空格。又根据答案有缺失,答卷试卷号不匹配这个测试点有问题,那么我就锁定到这些代码里面。发现格式确实与题目不一样。发现到这么多的是格式问题,可能是自己看题目不够仔细。那么以后在生活和学习的过程中,我应该先仔细分析一下现象,不然很多时候都是会做无用功。然后要说比较难测试的点就是乱序输入,因为一般人都是会自己认为这个输入就是正常按顺序输入,但是有一个测试点是会修改输入的顺序。
第三次作业
1.这次作业变得更加难了,我十分艰难的没有全完成。当无效的学号引用引用的时候还是要对题目进行判断对错,我之前没有进行处理。
2.还有这个答案为空字符按正常处理,我也没有正确理解到底这个答案是题目中的答案还是答卷里面的答案,也测试过一些但是这个测试点依然通过不了。真的不想多说。
3.这次作业中最遗憾的是没有把删除题目这个功能给做好,有一个删除的方法,也有一个判断删除题目。
if (dataStore.getDeletedQuestions().contains(questionId)) {
System.out.println("the question " + questionId + " invalid~0");
i++; // 跳过已删除的题目
continue;
}
4.第三次作业是十分困难的,它让我感觉到自己对知识的掌握程度还远远不够,还需要花更多时间去学习。测试点很多,一个一个的解决难度也很大,所以最后只能完成了一些测试点,说时间不够也只是自己不够努力。如果能够把所有可以利用的时间来进行设计题目中的需求,那么最后也可以完成代码。
四、改进建议
第一次作业
其实第一次作业也没有什么可改的本来就很少,唯一可能要改动的就是输入输出不应该大面积在Main类的main方法里面。那么优化代码时可以把输入和输出放在新建的一个输入类和一个输出类里面,这样Main类里面更加干净,调用起来也比较方便。比如一些类优化SplitshiyigeshuruQuestion类,使用正则表达式简化字符串处理。优化setTopicNum方法,如果需要设置题目数量,可以直接清空topics并重新设置。
第二次作业
第二次作业就是类会看上去比较多,而且一些类确实也不会用到太多方法。那么进行改进时会把类改少一些。优化正则表达式,使用更高效的正则表达式匹配,减少不必要的编译和匹配次数。优化输入解析,将输入解析逻辑封装到单独的方法中,使主逻辑更清晰。优化输出格式,使用 StringBuilder 来构建输出字符串,减少频繁的System.out.print调用。增加异常处理,增加对输入格式错误的处理,提高程序的健壮性。优化数据结构,使用Map来存储题目和试卷,提高查找效率。
第三次作业
第三次作业难度上比较高。对于改进建议可以减少重复代码,提取公共方法。将解析输入和格式化输出的重复代码提取到单独的方法中,避免代码冗余。例如,可以创建一个 parseInput 方法来统一处理不同类型的输入解析。创建一个formatOutput方法来统一处理输出格式。优化输入解析,使用 switch 语句或枚举。将输入类型(如 #N:、#T: 等)映射到枚举类型,使用 switch 语句来处理不同的输入类型。这样可以使代码更加清晰和易于维护。优化输出格式,使用 StringBuilder。在构建输出字符串时,使用 StringBuilder 而不是频繁的 System.out.print 调用,以提高性能。例如,在AnswerProcessor类中,可以使用 StringBuilder 来构建最终的输出结果。
五、总结
1.通过对本阶段三次题目集的编程及总结,知道了面向对象编程的思想与面向过程不一样。深入理解了类和对象的概念,还需要继续学习如何设计类和方法来实现复杂的功能。学习了封装和多态等面向对象的基本原则。这三次作业还没有涉及到继承,但是在课外也进行了一定的学习。在数据结构方面,学会了使用 Map、List、Set 等集合类来高效地管理和操作数据。了解了不同数据结构的优缺点及其适用场景。对于异常处理方面,学会了如何使用 try-catch 块来捕获和处理异常,提高了程序的健壮性和可靠性。了解了常见的异常类型及其处理方式。在代码优化上,学会了如何通过提取公共方法、减少重复代码来提高代码的可读性和可维护性。了解了 StringBuilder 的使用方法,提高了字符串操作的性能。
2.在输入输出处理上,学会了如何从标准输入读取数据,并将其解析为程序所需的格式。掌握了如何将程序的结果格式化并输出到控制台。需要进一步学习及研究的地方,高级数据结构和算法,正则表达式还不是很熟练,需要更多时间去掌握。除此之外,对于面向对象的课程里面的一些概念不是特别了解,类图、顺序图不是很会画,耦合度也不会看图来了解。这些需要进一步学习。然后就是类与类之间的关系也不是特别熟悉,只能知道大概。
3.对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见:对于教师,增加互动环节。在课堂上增加更多的互动环节,如提问、讨论等,提高学生的参与度和兴趣。提供更多示例。提供更多的实际案例和示例代码,帮助学生更好地理解和应用所学知识。作业应该有多样化作业形式,除了传统的编程作业,可以增加一些开放性的项目作业,鼓励学生发挥创造力。并且及时反馈,及时批改作业并提供详细的反馈,帮助学生发现和改正问题。