JAVA 前三次题目集总结

news/2024/10/23 4:02:05

在过去的一个月里完成了java的前三次大作业对于JAVA的语法以及面向对象编程还不台上手,接下来说前三次大作业。
前三次大作业要是围绕答题判题系统展开的每次作业都在完善这个程序的功能可以说
1.第一次作业判分功能
在第一次作业阶段,核心任务是建立一个能够接收题目信息和答题信息,并能够进行基本判分的系统。
• 核心功能:
题目处理: 通过 Question 类存储题目内容和正确答案,为判分提供基础。
答卷处理: AnswerSheet 类用于收集学生答案,包括学生ID和他们的答案。
判分逻辑: 对学生提交的答案与标准答案进行对比,判断答题的正确性。
• 技术实现:
使用Java的数据结构如 Map 和 List 来存储题目和答案。
对输入的处理采用简单的字符串解析技术,以提取关键信息。
• 挑战与解决方案:
初始阶段主要挑战是确保所有题目和答案能正确录入并能进行准确判分。
解决方案是通过单元测试确保每部分输入正确处理和输出预期结果。
2.第二次作业管理与总分校验
第二次作业引入试卷的概念,增加了试卷与题目的关联管理以及试卷总分的验证。
• 新增功能:
试卷类的引入: TestPaper 类管理一张试卷中的题目和各题的分值。
总分验证: 检查每张试卷的总分是否为100分,如果不是则发出警告。
• 技术深化:
扩展了对输入的解析,包括处理更复杂的字符串格式和关联数据。
引入逻辑判断试卷总分是否合规。
• 挑战与解决方案:
确保试卷中的题目与题库中题目正确关联,并正确计算总分。
通过逐项添加题目到试卷并实时计算总分来解决问题。
3.第三次作业的错误管理和数据完整性
第三次作业不仅增加了对学生信息的管理,还增强了对错误和数据完整性的管理。
• 扩展功能:
学生信息管理: 增加对学生的信息处理,使得每张答卷都能与具体学生关联。
题目删除功能: 允许从系统中删除题目,即使这些题目已经被试卷引用。
• 健壮性提升:
引入错误处理机制,如输入格式错误、不存在的试卷号或学生号等。
对被删除的题目在输出时提供特别提示,如"题目无效"。
• 挑战与解决方案:
处理输入的复杂性和数据的一致性问题,如确保即使题目被删除,相关的试卷仍能正确处理。
采用数据验证和异常处理策略,增强系统的健壮性和用户的错误反馈。

代码分析
第一次作业:
类图:

顺序图:

解析输入逻辑:parseInput 方法

    try {if (line.startsWith("#N:")) {// 解析题目信息String[] parts = line.split(" #Q:| #A:");int questionId = Integer.parseInt(parts[0].substring(3));String questionContent = parts[1];String answer = parts[2];questions.put(questionId, new Question(questionContent, answer));} else if (line.startsWith("#T:")) {// 解析试卷信息String[] parts = line.substring(3).split(" ");int paperId = Integer.parseInt(parts[0]);Paper paper = new Paper(paperId);for (int i = 1; i < parts.length; i++) {String[] questionParts = parts[i].split("-");int questionId = Integer.parseInt(questionParts[0]);int score = Integer.parseInt(questionParts[1]);paper.addQuestion(questionId, score);}papers.put(paperId, paper);} else if (line.startsWith("#X:")) {// 解析学生信息String[] studentInfos = line.substring(3).split("-");for (String studentInfo : studentInfos) {String[] parts = studentInfo.split(" ");String studentId = parts[0];String name = parts[1];students.put(studentId, new Student(name));}} else if (line.startsWith("#S:")) {// 解析答卷信息String[] parts = line.split(" ");int paperId = Integer.parseInt(parts[0].substring(3));String studentId = parts[1];AnswerSheet answerSheet = new AnswerSheet(paperId, studentId);for (int i = 2; i < parts.length; i++) {if (parts[i].startsWith("#A:")) {String[] answerParts = parts[i].substring(3).split("-");int questionIndex = Integer.parseInt(answerParts[0]);String answer = answerParts[1];answerSheet.addAnswer(questionIndex, answer);}}answerSheets.add(answerSheet);} else if (line.startsWith("#D:N-")) {// 解析删除题目信息int questionId = Integer.parseInt(line.substring(5));deletedQuestions.add(questionId);if (questions.containsKey(questionId)) {questions.get(questionId).setValid(false);}} else {throw new IllegalArgumentException("wrong format:" + line);}} catch (Exception e) {System.out.println("wrong format:" + line);}
}

优点:
分支清晰:根据不同的输入前缀 (#N:, #T:, #X:, #S:, #D:N-),程序通过 if-else 结构对不同类型的输入进行处理,逻辑简单明了,便于理解。
数据解析合理:对于题目、试卷、学生信息、答卷和删除题目,使用字符串拆分 (split) 的方式,从输入中提取数据,结合具体的标识符提取相关字段,能够有效处理复杂格式。
良好的容错性:每个分支都使用 try-catch 捕获异常,如果遇到格式错误的输入,程序可以避免崩溃,并输出提示,继续处理后续输入。
可扩展性强:基于输入前缀的模式(如 #N:, #T:),可以很容易添加新的输入处理逻辑,增加系统功能。
缺点:
输入格式依赖性高:代码对于输入格式的假设比较严格,输入格式的稍微变化(如少一个空格或格式不一致)可能会导致解析失败并输出 "wrong format" 提示,但不能提供详细的错误信息帮助调试。
代码冗余:多个 if-else 分支都有类似的字符串解析操作,比如分割字符串、取子串等,虽然功能不同,但某些部分可以进一步重构和优化,减少重复代码。
错误处理简单:catch 中仅简单地输出错误提示,对于不同的异常类型(如空输入、非法格式等)没有详细的区分,也没有额外提示如何修复输入错误。
硬编码解析逻辑:解析逻辑通过直接字符串切割和硬编码索引来提取数据,虽然简单但不灵活,特别是当输入格式发生变化时(如题目信息不止两部分)会变得难以维护和扩展。

成绩处理逻辑:processResults 方法

static void processResults() {// 计算每张试卷的总分并生成警示信息for (Map.Entry<Integer, Paper> entry : papers.entrySet()) {Paper paper = entry.getValue();int totalScore = paper.getQuestions().values().stream().mapToInt(Integer::intValue).sum();if (totalScore != 100) {System.out.println("alert: full score of test paper" + entry.getKey() + " is not 100 points");}}// 处理每个学生的答卷for (AnswerSheet answerSheet : answerSheets) {Paper paper = papers.get(answerSheet.getPaperId());if (paper == null) {System.out.println("The test paper number does not exist");continue;}Student student = students.get(answerSheet.getStudentId());if (student == null) {System.out.println(answerSheet.getStudentId() + " not found");continue;}// 记录每个题目的结果和得分List<String> questionResults = new ArrayList<>();List<String> scoreResults = new ArrayList<>();int totalScore = 0;for (Map.Entry<Integer, Integer> questionEntry : paper.getQuestions().entrySet()) {Integer questionId = questionEntry.getKey();Integer score = questionEntry.getValue();// 检查题目是否存在于题库中Question question = questions.get(questionId);if (question == null) {// 题目不存在的情况questionResults.add("non-existent question~0");scoreResults.add("0");} else if (!question.isValid()) {// 题目无效(已删除)的情况questionResults.add("the question " + questionId + " invalid~0");scoreResults.add("0");} else {// 题目有效,继续检查学生作答情况String studentAnswer = answerSheet.getAnswers().getOrDefault(questionId, "answer is null").trim();if (studentAnswer.equals("answer is null")) {// 学生未作答该题目questionResults.add("answer is null");scoreResults.add("0");} else {// 学生作答,判断是否正确boolean correct = studentAnswer.equals(question.getAnswer());int obtainedScore = correct ? score : 0;totalScore += obtainedScore;questionResults.add(question.getContent() + "~" + studentAnswer + "~" + (correct ? "true" : "false"));scoreResults.add(String.valueOf(obtainedScore));}}}// 输出题目的结果for (String result : questionResults) {System.out.println(result);}// 输出学生总成绩及题目得分,格式为: 学号 姓名: 每题得分 总分~总分String scoreString = String.join(" ", scoreResults);  // 将每题得分用空格连接System.out.println(answerSheet.getStudentId() + " " + student.getName() + ": " + scoreString + "~" + totalScore);}
}

优点:
试卷总分验证:系统首先计算每张试卷的总分并检查是否为 100 分,提供合理的警示机制,如果分值设置有误,可以及时发现问题。
答卷处理细致:处理每个学生的答卷时,针对不同情况提供详细判断,包括题目不存在、题目被删除、学生未作答、学生答题错误等。这种细化的判断使得程序对各种答题场景都有较好的处理能力。
实时输出结果:程序在处理每个答卷时,会实时输出每道题的答题情况以及每个学生的成绩,这有助于快速获取结果,便于调试。
答案与分数分离:将学生的每题答题情况与得分分别存储在两个不同的列表 (questionResults 和 scoreResults),使得代码逻辑清晰,输出时可以灵活组合展示信息。
缺点:
复杂性增加:为了处理各种可能的输入情况(题目不存在、题目无效、学生未作答等),代码中存在多层嵌套 if-else,导致代码的复杂度较高,后续维护难度可能较大。
硬编码逻辑:对于题目的正确性判断和分数计算,都采用了硬编码的方式,没有提供灵活的评分机制。如果以后需要扩展,例如引入部分正确、题目权重等,修改现有代码的成本会比较大。
缺少统一的错误处理机制:每种错误(如无效题目、未作答)都在分支内单独处理,虽然能应对各种情况,但没有统一的错误处理机制。如果增加更多种类的错误类型,代码将变得更难维护。
代码冗余:对于题目结果和分数的记录与输出,虽然分离了答题结果和得分,但代码仍然存在一定冗余,例如每个条件分支都需要分别处理 questionResults 和 scoreResults,可以考虑进一步简化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/74893.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

数据结构 - 树,三探之代码实现

本文介绍了使用数组和链表两种方式实现二叉树,包括初始化、节点操作(如获取、添加、删除)、以及遍历方法(前序、中序、后序、层次遍历)。测试代码已上传至代码库。书接上回,今天和大家一起动手来自己实现树。相信通过前面的章节学习,大家已经明白树是什么了,今天我们主…

不限次数无广告的短网址生成工具推荐

无论是在社交媒体、营销推广还是日常分享,短网址都能让我们更加便捷地分享内容。然而,在众多的短网址生成工具中,用户常常会遇到一些令人头疼的问题:跳转次数限制、插入广告等等。本文将为大家推荐一款不限次数且无广告的短网址生成工具——小码短链接,并详细介绍其优势。…

使用文件重定向

在Linux终端使用了下文件重定向在试的时候命令比较混乱,再重新捋一下:首先使用vim编辑器创建一个名为test.cpp的文件。 具体内容如下:然后使用g++ -o test test.cpp命令编译生成可执行文件test。接着使用vim编辑器创建了输入文件data.txt 具体内容如下:再运行命令./test &l…

Linux环境PostGIS源码编译安装

前提条件 安装PostGIS之前必须先安装proj,geos,gdal 1、安装proj8 下载proj-8.1.0.tar.gz :http://download.osgeo.org/proj/proj-8.1.0.tar.gz [root@gyl soft]# tar xf proj-8.1.0.tar.gz [root@gyl soft]# cd proj-8.1.0 [root@gyl proj-8.1.0]# ./configure --prefix=/usr…

The 2022 ICPC Asia Xian Regional Contest 前六题

VP一场,成都赛前找手感,这次还不戳,前三题略讲The 2022 ICPC Asia Xian Regional Contest 签到题题解 CFJ J. Strange Sum 易证最多只能选两个,从大到小排序后 \(\max(0, a_1) + \max(0, a_2)\) 即为所求。 void solve(){cin>>n;vector<ll>a(n+1);for(int i=1;…

利用数组处理批量数据

数组是一组有序数据的集合。数组中各数据的排列有一定规律,下标代表数据在数组中的序号 用一个数组名和下标来唯一的确定数组中的元素 数组中的每一个元素都属于同一个数据类型。不能把不同类型的数据放在同一个数组中 将数组和循环结合起来,可以有效的处理大批量的数据 怎样…

执行yum install 的时候提示【没有可用的软件包】的解决方案

这种情况,可能是yum 源不正确的问题,解决方案如下: 1.执行cd /etc/yum.repos.d,进入这个目录下,查看文件是否存在并检查文件内容的正确性 2、CentOS-Base.repo文件可以在网上下载一个,以下是范文# CentOS-Base.repo # # The mirror system uses the connecting IP addres…

newc++file.cpp在哪

本人的newc++file.cpp文件在C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\VCProjectItems可以在这个cpp文件里面自己选择是否写#define _CRT_SECURE_NO_WARNINGS 如果写了,则在visual studio中新建的cpp文件都有这个这个预处理命令主要是为…