题目集1~3总结性Blog

hzh-135 / 2024-12-19 / 原文

一.前言

1.题目集1

(1)知识点:

7-1 设计一个风扇Fan类:
类的设计:有参构造方法 ,无参构造方法,toString()的方法返回描述对象的字符串,成员变量(数据域)的访问器和修改器的设计。
7-2 类和对象的使用:
类和对象的使用,构造方法的重载。
7-3 成绩计算-1:
类、数组的基本运用。
7-4 成绩计算-2:
关联类,关联关系的实现。

7-5 答题判题程序-1:

  1. 类的设计与封装
  • 代码包含三个主要类:TitleTestPaperAnswerSheet,分别表示题目、试卷和答题纸的概念。
  • 每个类封装了特定的数据和方法,实现了类的职责分离,便于管理和维护:
  • Title:封装了题目的 ID、内容和标准答案,并提供了 checkAnswer 方法用于答案验证。
  • TestPaper:存储 Title 对象,并提供方法添加题目、按 ID 获取题目、检查题目答案等。
  • AnswerSheet:存储用户答案和评判结果,关联一个 TestPaper 对象,并实现了答案存储和评判结果输出的方法。
  1. 集合与泛型
  • 代码使用了 MapList 两种常用集合来存储数据。
  • TestPaper 类中的 titles 使用 TreeMap,根据 titleID 的顺序存储 Title 对象,便于按题号排序。
  • AnswerSheet 类中的 answersJudgeresults 使用了 List,以顺序存储用户答案和评判结果。
  • 泛型的使用:TestPaper 类的 Map<Integer, Title> 指定了 TreeMap 的键和值的类型,确保了键为 Integer,值为 Title
  • 注意:AnswerSheet 类中的 answersJudgeresults 应使用泛型声明(如 List<String>List<Boolean>),以提高类型安全性。
  1. 正则表达式的使用
  • 正则表达式 PatternMatcher 被用于从输入数据中提取题目编号、问题内容和标准答案,格式为 #N: <题号> #Q: <问题> #A: <答案>
  • 这部分代码利用了捕获组匹配来解析题目的结构,使代码更简洁、易于维护。
  1. 输入与数据处理
  • 输入的处理采用 Scanner 从控制台逐行读取用户输入。Pattern 用于解析题目输入,并在 Main 方法中将解析的题目添加到 TestPaper
  • 在处理用户答案时,代码使用 split 方法去除 #A: 前缀,并存储在 AnswerSheet 类的 answers 列表中。
  1. 关联关系
  • TestPaperTitle:一种聚合关系,TestPaper 由多个 Title 组成,并将 Title 存储在 Map 中。
  • AnswerSheetTestPaper:一种关联关系,AnswerSheet 类依赖于 TestPaper 类来检查答案的正确性。
  1. 面向对象编程原则
  • 单一职责原则:每个类专注于单一功能,便于代码的解耦和维护。
  • 封装:TitleTestPaperAnswerSheet 类都对内部数据进行了封装,仅通过公共方法访问。
  • 高内聚低耦合:各类之间依赖关系清晰,降低了耦合度,使各类可以独立工作。
  1. 逻辑控制与条件判断
  • Main 方法中有多个条件判断,用于处理数据输入的不同阶段。
  • AnswerSheet 类中的 printAnswersAndJudgeResults()方法,通过条件判断决定结果输出格式(如最后一组结果不添加空格)。
  1. 边界与错误处理
  • checkAnswer 方法判断用户答案是否匹配标准答案,避免了因大小写或空格导致的错误。
  • 代码没有对输入的格式进行严格检查,可以增加对输入格式的边界检查和错误处理,确保输入数据的有效性。

9.字符串处理:

  • 对用户输入进行清理和处理,例如使用 trim() 方法去除多余的空格,以及通过 replace() 方法去掉特定的前缀。

(2)题量、难度

前面几题题量小,难度小
最后一题题量较小,但是难度较大

2.题目集2

(1)知识点:

7-1 手机按价格排序、查找:

  1. 接口实现与比较操作
  • MobilePhone 类实现了 Comparable<MobilePhone> 接口,重写了 compareTo 方法用于定义排序规则:
  • compareTo 方法中使用 Integer.compare(this.price, other.price) 实现了价格的升序排序。
  • 实现 Comparable 接口后,可以通过 Collections.sort()MobilePhone 对象进行自然排序(根据价格升序)。
  • 这是 Java 中定义排序规则的常用方式之一,使得对象可以直接参与排序操作。

2.ArrayList 的使用

  • ArrayList 用于存储 MobilePhone 对象。ArrayList 是一种动态数组,支持自动扩容,便于管理一组对象。
  • 代码通过 ArrayList 存储了三个 MobilePhone 对象,并通过 Collections.sort()ArrayList 中的对象排序。
  1. **Collections.sort() 方法
  • Collections.sort(mobilephoneList) 使用了集合工具类 Collections 提供的排序方法,可以对实现了 Comparable 接口的对象进行自然排序。
  • 由于 MobilePhone 实现了 Comparable 接口并定义了价格排序规则,Collections.sort() 可以直接对 ArrayList<MobilePhone> 排序。

7-2 sdut-oop-4-求圆的面积:

  1. 访问控制和封装
  • radius 属性被声明为私有 (private),只能通过 setRadiusgetRadius 方法进行访问和修改。这种封装方式保证了 radius 的值只能通过类中定义的接口进行操作,避免了直接访问带来的不安全性。
  • 使用 publicgetRadiussetRadius 方法,外部可以安全地访问和更新 radius 的值。同时在 setRadius 方法中对输入进行了验证,确保了 radius 的值始终是一个有效的正数。
  1. 面向对象的封装和数据验证
  • setRadius 和带参构造方法中,都加入了 radius 值的有效性验证,以确保 radius 始终为正数。
  • 使用这种数据验证机制确保对象的状态符合业务逻辑需求,避免因为无效数据导致的不正确计算或错误输出。
  1. 库函数的调用
  • getArea 方法用于计算并返回圆的面积,计算公式为 Math.PI * Math.pow(this.radius,2),使用了 Math 库中 PIpow 方法。
  • 使用单独的方法来计算面积可以提高代码的模块化,并使得调用者无需关心面积的计算逻辑,直接通过该方法得到结果。
  1. 控制台输入和对象属性修改
  • Main 类中,通过 Scanner 对象从控制台读取半径值,用 c2.setRadius(r1) 动态修改 c2 对象的 radius 值。
  • 这种交互方式模拟了用户动态输入的情境,展现了如何通过控制台输入与对象方法交互,实时更新对象的属性。
  1. 格式化输出
  • 使用 System.out.printf("%.2f%n", c1.getArea()) 格式化输出面积,保留两位小数。%.2f 控制浮点数的输出格式,.2 表示保留两位小数,%n 表示换行。
  • 格式化输出提升了输出的美观性,尤其是在需要控制精度或格式的场合。

7-3 Java类与对象-汽车类
代码的补充,解读

7-4 答题判题程序-2

  1. 类的设计与面向对象编程
  • Title 类:代表考试中的一道题目,包含题目ID、内容、标准答案,以及用于验证用户答案的 checkAnswer 方法。
  • TestPaper 类:表示一张试卷,包含题目列表及其对应分数,提供方法来添加题目、获取题目、获取题目分数及计算试卷总分。
  • AnswerSheet 类:表示一份答题卡,存储用户的答案列表,使用 judgeAnswers 方法来自动判分。printAnswersAndJudgeResultsprintScores 分别用于输出答题和分数结果。
  1. 正则表达式
  • 正则表达式用于解析输入数据,使程序能动态读取并提取题目内容和答卷数据:
  • titlePattern:匹配题目定义行,例如 #N: titleID #Q: question #A: standardAnswer
  • testPattern:匹配试卷定义行,例如 #T: testID titleID-score
  • answerPattern:匹配答题行,例如 #S: testID #A: answer
  1. 数据结构 (集合类和Map)
  • 使用 Map 组织试卷和题目,便于快速根据题目ID查找题目信息。
  • 使用 List 存储答案和判分结果,在 AnswerSheet 类中对用户答案进行逐题判断。
  1. 自动判分与条件判断
  • 答案校验:AnswerSheet 类中的 judgeAnswers 方法对用户答案进行逐题判分,判断对错并累加总分。
  • 分数检查:在试卷定义时立即检查总分是否为100分,并输出相应警告信息。
  1. 代码逻辑的简化与优化
  • 代码采用 LinkedHashMap 来保证题目顺序,List 存储判分结果,Map 映射题目ID与分数,避免了嵌套循环,代码简洁易读。

(2)题量、难度

前面几题题量小,难度小
最后一题题量较大,难度较大

3.题目集3

(1)知识点

7-1 面向对象编程(封装性):
类的封装。
7-2 jmu-java-日期类的基本使用:

  1. Java时间API (java.time)
  • LocalDate 类:代表日期对象,且只包含年、月、日,不包含时间。
  • ChronoUnit 枚举:用于计算日期间隔,提供了DAYSMONTHSYEARS等多种常量,可以简化日期操作。
  1. 日期解析与异常处理
  • LocalDate.parse(dateStr):将字符串解析为 LocalDate 对象,要求输入符合“yyyy-MM-dd”格式。
  • 异常处理:parseDate 方法捕获 DateTimeException 异常,以便处理非法日期并返回 null,这样可以优雅地应对用户输入的错误格式或无效日期。
  1. 闰年判断
  • isLeapYear 方法:调用 LocalDateisLeapYear 方法判断日期所在年份是否为闰年。使用闰年判断可以识别2月是否有29天。
  1. 日期差计算
  • 天数差:使用 ChronoUnit.DAYS.between(start, end) 计算天数间隔,适用于直接计算天数。
  • 年数和月数差:通过日期对象的 getYeargetMonthValue 计算年数差和月数差,以获取大概的年份和月份间隔。
  • 由于年数和月数间隔的计算并未考虑日期的精确性(如考虑“2024-01-01”到“2025-12-01”之间的实际月份差),年数和月数差计算方法可视作一种基础近似。
  1. 日期信息的提取
  • 使用 LocalDate 的方法提取以下日期信息:
  • getDayOfYear():获取日期在一年中的位置。
  • getDayOfMonth():获取日期在当月的位置。
  • getDayOfWeek():获取日期是星期几。

7-3 答题判题程序-3:

  1. 面向对象设计
  • Title类:封装了题目信息,包括题号、内容、标准答案、删除标记及答案校验方法。
  • TestPaper类:封装了试卷信息,包括题目排序与分数、总分计算等功能。
  • AnswerSheet类:用于封装答题信息,包含用户答案与判分结果等。
  • Main类:作为主程序控制流,负责处理输入、管理题库与试卷、生成答卷并输出结果。
  1. 集合和映射的使用
  • Map映射:Map在多处用于将题目编号、题目内容、试卷与学生答案等数据关联,如orderToTitleID(题目顺序到ID的映射)、titles(试卷题目集合)等。
  • Set集合:Set用于存储不可用题目ID,便于检测无效题目。
  • List集合:在判分时用于存储每道题的判断结果(对错),并在打印判分结果时循环取用。
  1. 正则表达式解析
  • 正则表达式解析输入:通过多组正则表达式(如titlePatterntestPattern等)解析不同格式的输入行,用以抽取题目信息、试卷分数、学生信息等。
  • 格式检查与提示:未匹配的行通过else条件抛出“格式错误”提示,确保用户输入符合规范。
  1. 异常处理
  • 格式错误检测:在用户输入答案时,通过判断输入格式是否符合预期,若不符则抛出IllegalArgumentException并提示“格式错误”。
  • 空输入跳过:跳过空白或格式不符的答案字符串,以防止程序因无效数据而崩溃。
  1. 数据封装与层次化设计
  • 代码将不同功能封装在不同类中,并通过Main类协调各个模块,保证了代码的可读性、扩展性和易维护性。例如,AnswerSheet封装了答题判分逻辑,而TestPaper则负责试卷信息和分数管理,使得各类之间职责明确。

(2)题量、难度

前面几题题量小,难度小
最后一题题量较大,难度较大

二.设计与分析

各题目集前面几题都相对简单,我们这里重点分析最后一题。

7-5 答题判题程序-1:

类图:

顺序图:

程序流程:

以下是这个程序的流程和主要函数调用关系:

程序流程概述

  1. 主程序入口 (Main.main)
  • 程序从 main 方法开始,通过 Scanner 从输入读取题目数量,并逐一输入每个题目的详细信息。
  • 每个题目信息以特定格式提供 (#N:<题号> #Q:<题目内容> #A:<标准答案>),程序使用正则表达式进行解析。
  • 将每个解析出的题目生成 Title 对象,存储到 TestPaper 中。
  • 然后,程序读取用户答案,提取每个答案,并将其传递给 AnswerSheet 进行处理。
  1. 题目和答案处理流程
  • 将所有用户答案存储并在 AnswerSheet 中调用 saveAnswers 方法进行判定。
  • saveAnswers 方法遍历用户答案,将每个答案与 TestPaper 中的标准答案对比,判断对错并存储结果。
  1. 输出判定结果
  • 通过 AnswerSheet.printAnswersAndJudgeResults 方法,依次输出每个题目内容及用户答案,然后输出每个判定结果(对错)。

关键类与方法

  1. Title
  • 表示单个题目及其标准答案。
  • 主要方法
  • checkAnswer:对比用户答案是否与标准答案一致(忽略大小写和空格)。
  1. TestPaper
  • 管理多个 Title 对象的集合,以 Map 存储并支持按题号排序。
  • 主要方法
  • addTitle:向 titles 中添加一个题目。
  • getTitleByID:根据题号获取特定题目。
  • checkAnswer:调用 Title.checkAnswer 检查特定题目的答案。
  1. AnswerSheet
  • 表示用户提交的答案,与标准答案对比并保存对错结果。
  • 主要方法
  • saveAnswers:接受用户答案列表,清理无效字符并检查每个答案是否正确,将结果存储到 Judgeresults 中。
  • printAnswersAndJudgeResults:输出题目内容、用户答案及判断结果。
  1. Main
  • 程序入口,负责读取输入、初始化 TestPaperAnswerSheet,并调用其方法完成操作。
  • 主要流程
  • Pattern 正则表达式解析输入,将题目和答案数据提取并存储。
  • 检查输入的用户答案格式,调用 AnswerSheet.saveAnswers 保存并判定答案正确性。
  • 最后,调用 AnswerSheet.printAnswersAndJudgeResults 输出所有结果。

函数调用关系

Main.main
├── TestPaper.addTitle (创建并添加题目到 TestPaper)
│   └── Title (创建 Title 对象)
│
├── AnswerSheet.saveAnswers (保存和判断答案)
│   ├── TestPaper.checkAnswer (在 TestPaper 中检查答案)
│   │   └── Title.checkAnswer (调用 Title 判断答案是否正确)
│   └── 结果保存至 Judgeresults
│
└── AnswerSheet.printAnswersAndJudgeResults (输出题目及判定结果)

重点代码分析:

1. checkAnswer 方法

public boolean checkAnswer(String answer) {
    return standardAnswer.equalsIgnoreCase(answer.trim());
}
  • 功能:将 answer 首尾空格去掉后(trim()),与 standardAnswer 进行忽略大小写的比较。
  • 参数answer 是用户输入的答案字符串。
  • 返回值:若用户答案和标准答案一致(忽略大小写和首尾空格差异),返回 true;否则返回 false

2. addTitle方法

public void addTitle(Title title) {
    titles.put(title.getTitleID(), title);
}
  • 功能:将一个 Title 对象添加到 titles 集合中。
  • 参数title 是一个 Title 对象,代表一个题目。
  • 细节:使用 title.getTitleID() 作为键,将 title 存入 Map 集合 titles 中,确保题目通过其唯一 ID 来索引。

3. getTitleByID方法

public Title getTitleByID(int titleID) {
    return titles.get(titleID);
}
  • 功能:根据题目 ID 获取对应的 Title 对象。
  • 参数titleID 是题目的唯一标识符。
  • 返回值:如果找到匹配的题目 ID,返回对应的 Title 对象;否则返回 null

4. checkAnswer方法

public boolean checkAnswer(int titleID, String answer) {
    Title title = getTitleByID(titleID);
    return title != null && title.checkAnswer(answer);
}
  • 功能:检查用户对特定题目的答案是否正确。
  • 参数titleID 为题目 ID,answer 为用户提供的答案。
  • 返回值:若题目 ID 存在且答案正确,返回 true;否则返回 false
  • 细节:调用 getTitleByID 获取题目对象,然后调用该题目的 checkAnswer 方法判断答案是否正确。

5. getSortedTitles方法

public Map<Integer, Title> getSortedTitles() {
    return titles;
}
  • 功能:返回包含所有题目的 Map 集合。
  • 返回值:按题目 ID 排序的 Map<Integer, Title> 集合,因为 titles 是一个 TreeMap(自动按键排序)。

6. saveAnswers 方法

public void saveAnswers(String[] UserAnswers) {
    for (int i = 0; i < UserAnswers.length; i++) {
        int titleID = i + 1;
        String cleanedAnswer = UserAnswers[i].replace("#A:", "").trim();  // 去除 #A: 前缀并去掉空格
        answers.add(cleanedAnswer);
        boolean IsCorrect = testPaper.checkAnswer(titleID, cleanedAnswer);
        Judgeresults.add(IsCorrect);
    }
}
  • 功能:从 UserAnswers 数组中提取每个用户答案,清理掉无关字符并与标准答案对比,存储判定结果。
  • 步骤
    1. 遍历用户答案数组 UserAnswers
    2. 计算题目 ID(假设答案顺序与题目 ID 对应):
      题目 ID = i + 1,假设 UserAnswers[0] 是第 1 题的答案,以此类推。
    3. 清理用户答案:去掉前缀 #A:,并去掉首尾空格。
    4. 将清理后的答案添加到 answers 列表中。
    5. 调用 testPaper.checkAnswer 检查答案正确性,将结果存入 Judgeresults 列表。

7. printAnswersAndJudgeResults 方法

public void printAnswersAndJudgeResults() {
    Map<Integer, Title> sortedTitles = testPaper.getSortedTitles();

    for (Integer titleID : sortedTitles.keySet()) {
        Title title = sortedTitles.get(titleID);
        if (title != null) {
            System.out.println(title.getContent() + "~" + answers.get(titleID - 1));
        }
    }

    for (int i = 0; i < Judgeresults.size(); i++) {
        System.out.print(Judgeresults.get(i));
        if (i < Judgeresults.size() - 1) {
            System.out.print(" ");
        }
    }

    System.out.println();
}
  • 功能:输出每道题目的内容和用户答案,并打印每个答案的判定结果(true 表示正确,false 表示错误)。
  • 步骤
    1. 获取题目集合 sortedTitles
    2. 遍历 sortedTitles 的每个题目 ID:
      获取对应题目内容和用户的答案。
      格式化输出为 题目内容~用户答案
    3. 遍历 Judgeresults 列表,输出判定结果 truefalse,中间用空格分隔。
7-4 答题判题程序-2:

类图:

顺序图:

程序流程:

程序整体流程

  1. 输入解析和存储
  • 程序通过 Scanner 接收多行输入并存储在 inputLines 列表中,直到遇到 "end"
  • 分析输入行是否匹配题目、试卷或答卷的格式,并将解析结果存储在相应的集合中。
  1. 题目、试卷和答案的解析
  • 逐行解析 inputLines,判断每行是否是题目、试卷或答卷。
  • 将解析得到的题目信息存储在 allTitles 中,试卷信息存储在 testPapers 中,答卷则用于创建 AnswerSheet
  1. 试卷验证和输出
  • 在添加每张试卷时,检查其总分是否等于100分,若不等于100分,输出警告信息。
  • 每次创建 AnswerSheet 对象时,调用其方法输出答题和判分结果。

核心函数调用关系

  1. Main 类
  • 主要负责处理输入,并根据输入构建 TitleTestPaperAnswerSheet 对象。
  • 调用顺序
  • 调用 Title 构造函数创建题目。
  • 调用 TestPaper.addTitle() 为试卷添加题目和分数。
  • 调用 AnswerSheet 构造函数解析用户**,并输出答题和判分结果。
  1. Title 类
  • Title 对象保存题目内容和标准答案。
  • checkAnswer:检查用户答案是否与标准答案匹配,忽略大小写和空格。
  1. TestPaper 类
  • 存储试卷的题目、每道题的分数,并支持计算试卷总分。
  • addTitle:将 Title 对象和对应的分数添加到试卷中。
  • getScoreByTitleID:返回特定题目的分数。
  • getTotalScore:计算并返回试卷的总分。
  1. AnswerSheet 类
  • 保存用户的答案,判定其正确性,并根据答对的题目计算得分。
  • 主要方法
  • judgeAnswers:判定答案是否正确,更新判定结果和总得分。
  • printAnswersAndJudgeResults:按顺序打印题目、用户答案和判定结果。
  • printScores:打印每题得分和总分。

函数调用关系

+----------------------------------+
|           Main 类                |
+----------------------------------+
|                                  |
| 读取输入,存入 inputLines       |
| 遍历 inputLines,根据类型解析     |
|                                  |
| 如果是题目:                      |
|   - 解析题目,创建 Title 对象    |
|   - 存储到 allTitles             |
|                                  |
| 如果是试卷:                      |
|   - 解析试卷ID和题目分数          |
|   - 创建 TestPaper 对象           |
|   - 为 TestPaper 添加 Title       |
|   - 检查 TestPaper 总分是否为100  |
|                                  |
| 如果是答卷:                      |
|   - 解析答卷ID和用户答案          |
|   - 检查 TestPaper 是否存在       |
|   - 创建 AnswerSheet 对象         |
|   - 调用 AnswerSheet 方法打印结果  |
+----------------------------------+
              |
              v
+----------------------------------+
|           Title 类               |
+----------------------------------+
|  属性: titleID, content,        |
|       standardAnswer             |
|  方法:                          |
|    checkAnswer()                 |
+----------------------------------+
              |
              v
+----------------------------------+
|         TestPaper 类             |
+----------------------------------+
|  属性: testPaperID, titles,     |
|       scores                     |
|  方法:                          |
|    addTitle()                    |
|    getScoreByTitleID()           |
|    getTotalScore()               |
|    getTitles()                   |
+----------------------------------+
              |
              v
+----------------------------------+
|       AnswerSheet 类             |
+----------------------------------+
|  属性: testPaper, answers,      |
|       judgeresults, totalScore   |
|  方法:                          |
|    judgeAnswers()                |
|    printAnswersAndJudgeResults() |
|    printScores()                 |
+----------------------------------+

重点代码分析:

  1. checkAnswer 方法

    checkAnswer 方法用于判断用户输入的答案 answer 是否正确。它将用户答案 answer 和标准答案 standardAnswer 进行比较,忽略大小写和多余空格。如果相同,则返回 true

  2. addTitle 方法

    addTitle 方法用于添加问题和分数。每个问题由 Title 对象表示,它的 titleID 作为键存入 titles,而 score 则存入 scores

  3. getTotalScore 方法

    getTotalScore 方法计算并返回测试的总分。它遍历 scores 集合中的每个分数,累加求和并返回总分。

  4. judgeAnswers 方法

    judgeAnswers 方法用于对每个用户答案进行判断并记录结果。

  • 首先获取测试题目集合 titles
  • 逐一检查每个问题的答案,如果存在对应答案,则通过 checkAnswer 方法检查正确性,将结果存入 judgeresults
  • 如果答案正确,将对应题目的分数添加到总分 totalScore
  • 如果用户没有提供答案,则将 false 记录到 judgeresults
  1. printAnswersAndJudgeResults 方法
public void printAnswersAndJudgeResults() {
    Map<Integer, Title> sortedTitles = testPaper.getTitles();
    int i = 0;

    for (Integer titleID : sortedTitles.keySet()) {
        Title title = sortedTitles.get(titleID);
        String answer = i < answers.size() ? answers.get(i).trim() : "answer is null";

        if (answer.equals("answer is null")) {
            System.out.println("answer is null");
        } else {
            boolean isCorrect = judgeresults.get(i);
            System.out.println(title.getContent() + "~" + answer + "~" + isCorrect);
        }
        i++;
    }
}

printAnswersAndJudgeResults 方法用于打印用户答案及其正确性。

  • 遍历题目集合并获取每个题目的答案,如果没有提供答案,则输出 "answer is null"
  • 否则,显示问题内容、答案和判定结果 isCorrect,用 ~ 符号分隔。
  1. printScores 方法
public void printScores() {
        int i = 0;
        Map<Integer, Integer> scores = new LinkedHashMap<>();
        for (Integer titleID : testPaper.getTitles().keySet()) {
            if (i < answers.size() && judgeresults.get(i)) {
                scores.put(titleID, testPaper.getScoreByTitleID(titleID));
            } else {
                scores.put(titleID, 0);
            }
            i++;
        }

        int j = 0;
    int total = 0;
    int numScores = scores.size(); // 获取总的得分数量

    for (Integer score : scores.values()) {
        System.out.print(score); // 直接打印分数,不添加空格
        total += score;
        if (j < numScores - 1) { // 如果不是最后一个分数,添加空格
            System.out.print(" ");
    }
    j++;
}
    System.out.println("~" + total); // 打印总分,格式为 ~total

    }

printScores 方法用于打印每个问题的得分以及总分。

  • 通过遍历题目集合,检查答案是否正确,如果正确,将对应题目的分数添加到 scores,否则计为 0
  • 最后,将每个问题的得分按顺序打印,以空格分隔,并在最后添加总分
7-3 答题判题程序-3:

类图:

顺序图:


程序流程:

程序整体流程

  1. 程序入口 (main 方法)
  • 初始化数据结构testPapersallTitlesstudents等Map,用于存储试卷、题目和学生信息
  • 定义正则表达式:分别用于匹配输入中的题目、试卷、答案、删除和学生信息格式。
  • 读取输入:将所有输入行收集到 inputLines 列表中,并在读取结束时停止输入(即遇到"end"行)。
  1. 解析输入
    遍历 inputLines 中的每一行,根据不同类型信息调用对应的解析处理:
  • 题目信息解析(使用titlePattern):
    通过 Title 构造方法创建 Title 对象,存储到 allTitles

  • 调用关系new Title(...) -> allTitles.put(...)

  • 试卷信息解析(使用testPattern):
    创建 TestPaper 对象,并将题目和分数添加到试卷。

  • 调用关系new TestPaper(...) -> testPaper.addTitle(...) -> testPapers.put(...)

  • 分数检查:调用 getTotalScore 验证试卷总分是否为100分,不满足时输出警告。

  • 删除题目信息解析(使用deletePattern):
    通过题目ID找到 Title 对象,并调用 delete() 标记其为已删除。

  • 调用关系allTitles.get(...).delete()

  • 学生信息解析(使用studentPattern):
    将学生ID和姓名保存到 students Map。

  • 调用关系students.put(...)

  • 格式错误检查
    检查输入行是否符合格式,不符合则输出 "wrong format: " + line

  1. 处理答卷
  • 遍历 inputLines 再次匹配 answerPattern,获取答卷的测试ID、学生ID、学生答案。
  • 检查学生ID和试卷ID是否存在,若缺少则输出警告信息。
  • 若存在有效的测试ID,执行以下操作:
  1. 评分流程
  • 创建答题卡:根据学生答案数组 userAnswersWithOrder 创建 AnswerSheet 对象。

  • 调用关系new AnswerSheet(...)

  • 构造函数调用链:解析并存储答案后,调用 judgeAnswers() 方法对答案进行判断。

  • judgeAnswers() 方法
    遍历 testPaper 中的所有题目,检查每道题的答案是否正确,记录判定结果和总分:

  • 调用关系Title.checkAnswer(...) -> testPaper.getScoreByTitleID(...)

  1. 输出结果
  • 显示判定结果:调用 printAnswersAndJudgeResults() 输出每道题的内容、用户答案及正确性。

  • 调用关系:遍历 sortedTitles 并根据 nonExistentQuestionsisDeleted 状态处理各种答案输出。

  • 打印分数:调用 printScores 显示学生每道题的得分和总分。

  • 调用关系:遍历 scores 并累加打印。

函数调用关系总结

  1. main 调用 TitleTestPaperAnswerSheet 构造函数以存储题目、试卷和答题卡信息。
  2. AnswerSheet 构造函数 完成答案解析后自动调用 judgeAnswers 评分。
  3. 评分完成后,通过 printAnswersAndJudgeResultsprintScores 分别输出判定和得分信息。

总流程图

main()
│
├──> parse inputLines (title, test, delete, student info, answers)
│
├──> create TestPaper and Title objects
│
├──> create AnswerSheet for each answer -> judgeAnswers()
│    ├──> Title.checkAnswer() and score accumulation
│
├──> printAnswersAndJudgeResults()
│
└──> printScores()

整个程序流程主要是依次解析输入、构造对象、执行评分判断、并输出结果。

重点代码分析:

  1. 构造函数 AnswerSheet
public AnswerSheet(TestPaper testPaper, String[] userAnswers, Set<Integer> nonExistentQuestions) {
        this.testPaper = testPaper;
        this.nonExistentQuestions = nonExistentQuestions;

        // 解析答案,并在错误格式时提示
        try {
            for (String ans : userAnswers) {
                if (ans.trim().isEmpty()) {
                    continue; // 如果答案为空,则跳过
                }
                String[] parts = ans.replaceFirst("^#A:", "").split("-");
                if (parts.length != 2)
                    throw new IllegalArgumentException("wrong format: " + ans);
                int questionOrder = Integer.parseInt(parts[0].trim());
                String answerContent = parts[1].trim();
                answers.put(questionOrder, answerContent); // 标注问题顺序到答案
            }
            judgeAnswers();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
  • 参数testPaper(对应的试卷对象)、userAnswers(学生提交的答案数组)、nonExistentQuestions(不存在的题目集合)。
  • 功能:解析学生答案并存储到 answers Map 中,key 为题目顺序,value 为答案内容。
  • 异常处理:若格式不符合 #A:题号-答案,则抛出异常提示格式错误。
  • 评分:解析完成后调用 judgeAnswers 方法判定各题答案是否正确。
  1. 方法 judgeAnswers
private void judgeAnswers() {
        Map<Integer, Title> titles = testPaper.getTitles();

        for (Integer order : titles.keySet()) {
            Title title = titles.get(order);
            String answer = answers.get(order);

            if (answer == null || answer.trim().equals("")) {
                judgeresults.add(false);
                continue;
            }

            if (title == null || title.isDeleted()) {
                judgeresults.add(false);
            } else {
                boolean isCorrect = title.checkAnswer(answer);
                judgeresults.add(isCorrect);
                if (isCorrect) {
                    totalScore += testPaper.getScoreByTitleID(order);
                }
            }
        }
    }
  • 功能:遍历试卷中的所有题目,逐题判断答案的正确性。
  • 流程
    1. 取得试卷中每题的标题对象 Title 和学生提交的对应答案 answer
    2. 若答案为空,或题目已被删除,则标记为 false(答案错误),跳过该题。
    3. 若答案非空且题目有效,调用 checkAnswer 判断答案是否正确,结果加入 judgeresults 列表。
    4. 若答案正确,累加该题分数到 totalScore
  1. 方法 printAnswersAndJudgeResults
public void printAnswersAndJudgeResults() {
        Map<Integer, Title> sortedTitles = testPaper.getTitles();

        for (Integer order : sortedTitles.keySet()) {
            Title title = sortedTitles.get(order);
            String answer = answers.get(order);

            if ((answer == null && title.isDeleted())||(answer == null && nonExistentQuestions.contains(title.getTitleID()))) {
                System.out.println("answer is null");
            } else if (nonExistentQuestions.contains(title.getTitleID())) {
                System.out.println("non-existent question~0");
            } else if (title.isDeleted()) {
                System.out.println("the question " + title.getTitleID() + " invalid~0");
            } else if (answer == null) {
                System.out.println("answer is null");
            } else {
                boolean isCorrect = judgeresults.size() >= order && judgeresults.get(order - 1);
                System.out.println(title.getContent() + "~" + answer.trim() + "~" + isCorrect);
            }
        }
    }
  • 功能:输出每题的答案、判定结果,并考虑了多种题目状态(如无效题、缺失答案等)。
  • 流程
    1. 遍历试卷中的题目顺序,依次获取每道题的内容、学生答案、判定结果。
    2. 根据题目状态输出不同信息:
      若题目被删除或不存在,则输出 "the question [ID] invalid~0" 或 "non-existent question~0"。
      若答案为空,则输出 "answer is null"。
      否则输出题目内容、学生答案及正确性。
  1. 方法 printScores
 public void printScores(String studentID, String studentName) {
        Map<Integer, Integer> scores = new LinkedHashMap<>();
        int i = 0;

        for (Integer order : testPaper.getTitles().keySet()) {
            if (i < judgeresults.size() && judgeresults.get(i)) {
                scores.put(order, testPaper.getScoreByTitleID(order));
            } else {
                scores.put(order, 0);
            }
            i++;
        }

        System.out.print(studentID + " " + studentName + ": ");
        int total = 0;
        int size = scores.size();
        int count = 0;

        for (Integer score : scores.values()) {
            System.out.print(score);
            total += score;
            count++;
            if (count < size) {
                System.out.print(" ");
            }
        }

        System.out.println("~" + total);
    }
  • 参数:学生ID和姓名。
  • 功能:输出学生每题得分及总分。
  • 流程
    1. 遍历试卷题目,对已正确作答的题目,记录分数,否则得分为0。
    2. 格式化输出:先输出学生信息,再逐题输出分数,最后输出总分(~total)。

三.采坑心得

7-5 答题判题程序-1

  1. 格式错误
    问题:
    printAnswersAndJudgeResults()方法中打印判断结果时最后一个结果后面有空格,会造成格式错误

解决方法:

  • 确保最后一个判断结果输出后无空格

结果:

  1. 解析用户答案错误
    问题:
    saveAnswers(String[] UserAnswers)方法保存用户答案时没有正确解析输入的字符串,导致答案错误

解决方法:

  • saveAnswers(String[] UserAnswers)方法保存用户答案时清除前面的#A:
String cleanedAnswer = UserAnswers[i].replace("#A:", "").trim();  // 去除 #A: 前缀并去掉空格

结果:

3.没有正确清除空格,造成非零返回
问题:
在输入时如果多输了空格,没有完全按照格式,代码又没有清除,会造成非零返回
例如输入时题目数量前面多了个空格:

造成非零返回

解决方法:

  • 在输入和解析输入时使用trim()清除多余空格

结果:

7-4 答题判题程序-2

  1. 题目乱序
    问题:
    试卷题目的顺序与题号不一致造成答案输出不正确

解决方法:

  • TestPaper类中保存题目使用LinkedHashMap<>,确保题目乱序不会影响最终处理顺序
private Map<Integer, Title> titles = new LinkedHashMap<>();

结果:

2.答案为空输出错误
问题:
答案为空时只打印answer is null,而不打印其他形式
修改前:

for (Integer titleID : sortedTitles.keySet()) {
        Title title = sortedTitles.get(titleID);
        String answer = i < answers.size() ? answers.get(i).trim() : "answer is null";
            boolean isCorrect = judgeresults.get(i);
            System.out.println(title.getContent() + "~" + answer + "~" + isCorrect);
        
        i++;
    }

输入:

输出:

解决方法:

  • 在printAnswersAndJudgeResults()方法中增加输出判断,确保答案为空时只打印answer is null
for (Integer titleID : sortedTitles.keySet()) {
        Title title = sortedTitles.get(titleID);
        String answer = i < answers.size() ? answers.get(i).trim() : "answer is null";

        if (answer.equals("answer is null")) {
            System.out.println("answer is null");
        } else {
            boolean isCorrect = judgeresults.get(i);
            System.out.println(title.getContent() + "~" + answer + "~" + isCorrect);
        }
        i++;
    }

结果:

  1. 分值不足100提示信息
    问题:
    每次检测到试卷总分不为 100 时,立即输出警告,而不需要等到最后统一打印。
    修改前:
// 将警告信息暂时存储在列表中
                if (testPaper.getTotalScore() != 100) {
                    alerts.add("alert: full score of test paper" + testID + " is not 100 points");
                }
// 解析所有试卷后,输出警告信息
        for (String alert : alerts) {
            System.out.println(alert);
        }

结果:

解决方法:

  • 将警告信息的输出位置从结尾移到解析试卷的过程中,当发现总分不为 100 时立刻打印。

修改后:

// 立即检查总分是否为100并输出警告
                if (testPaper.getTotalScore() != 100) {
                    System.out.println("alert: full score of test paper" + testID + " is not 100 points");
                }

结果:

7-3 答题判题程序-3

  1. 解析答案逻辑问题
    问题:
    答卷信息中如果答案为空,解析答案会解析出错误,会有空格问题
    修改前:
// 解析答案,并在错误格式时提示
       try {
           for (String ans : userAnswers) {
               String[] parts = ans.replaceFirst("^#A:", "").split("-");
               if (parts.length != 2)
                   throw new IllegalArgumentException("wrong format: " + ans);
               int questionOrder = Integer.parseInt(parts[0].trim());
               String answerContent = parts[1].trim();
               answers.put(questionOrder, answerContent); // 标注问题顺序到答案
           }
           judgeAnswers();
       } catch (Exception e) {
           System.out.println(e.getMessage());
       }

输入:

输出:

解决方法:

  • 添加判断逻辑
// 解析答案,并在错误格式时提示
        try {
            for (String ans : userAnswers) {
                if (ans.trim().isEmpty()) {
                    continue; // 如果答案为空,则跳过
                }
                String[] parts = ans.replaceFirst("^#A:", "").split("-");
                if (parts.length != 2)
                    throw new IllegalArgumentException("wrong format: " + ans);
                int questionOrder = Integer.parseInt(parts[0].trim());
                String answerContent = parts[1].trim();
                answers.put(questionOrder, answerContent); // 标注问题顺序到答案
            }
            judgeAnswers();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

结果:

  1. 输出逻辑问题
    问题:
    如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。

修改前:

if (!students.containsKey(studentID)) {
                        System.out.println(studentID + " not found");
                        continue;}
                if (testPapers.containsKey(testID)) {
                    TestPaper testPaper = testPapers.get(testID);
                    AnswerSheet answerSheet = new AnswerSheet(testPaper, userAnswersWithOrder, nonExistentQuestions);
                    answerSheet.printAnswersAndJudgeResults();
                    
                    answerSheet.printScores(studentID, studentName);
                }

输入:

输出:

解决方法:

  • 改变输出逻辑
if (testPapers.containsKey(testID)) {
                    TestPaper testPaper = testPapers.get(testID);
                    AnswerSheet answerSheet = new AnswerSheet(testPaper, userAnswersWithOrder, nonExistentQuestions);
                    answerSheet.printAnswersAndJudgeResults();
                    if (!students.containsKey(studentID)) {
                        System.out.println(studentID + " not found");
                        continue;}
                    answerSheet.printScores(studentID, studentName);
                } 

结果:

  1. 顺序号和题号混淆错误
    问题:
    答卷信息中格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+...
    混淆了题号和顺序号照常答案错误
    这里答卷处理用的题号:

    对于这个输入:

    错误解析处理:

题目信息:

题目编号为2,题目内容为 "2+2=",答案为 "4"。
题目编号为1,题目内容为 "1+1=",答案为 "2"。
试卷信息:

试卷编号为1,包含题目2和题目1,分别对应的分数都是5分。
学生信息:

学生ID为20201103,姓名为Tom。
答案信息:

学生ID为20201103 即 Tom 的答题卡,参与试卷编号为1,回答如下:
问题1的回答为 “5”
问题2的回答为 “4”
结合解析的内容,代码应进行如下处理:

判断试卷总分是否为100。由于试卷总分是10(5+5),所以会输出警告信息。
判断答案的正确性:
题目1的正确答案是 "2" ,回答 "5" 是错误的。
题目2的正确答案是 "4" ,回答 "4" 是正确的。
计算学生的得分:
题目1得分是0分(错误)。
题目2得分是5分(正确)。
总得分是5分。
所以,代码运行后输出:

解决方法:

  • 使用顺序号

    正确解析:
    题目信息:

题目编号为2,题目内容为 "2+2=",答案为 "4"。
题目编号为1,题目内容为 "1+1=",答案为 "2"。
试卷信息:

试卷编号为1,包含题目编号为2的题目(在第一个位置,顺序号是1)和题目编号为1的题目(在第二个位置,顺序号是2),分别对应的分数都是5分。
学生信息:

学生ID为20201103,姓名为Tom。
答案信息:

学生ID为20201103 即 Tom 的答题卡,参与试卷编号为1,回答如下:
顺序号是1的题目的回答为 “5”
顺序号是2的题目的回答为 “4”
结合解析的内容,代码应进行如下处理:

判断试卷总分是否为100。由于试卷总分是10(5+5),所以会输出警告信息。
判断答案的正确性:
顺序号是1的题目,题目编号为2,正确答案是 "4" ,回答 "5" 是错误的。
顺序号是2的题目,题目编号为1,正确答案是 "2" ,回答 "4" 是错误的。
计算学生的得分:
顺序号是1的题目得分是0分(错误)。
顺序号是2的题目得分是0分(错误)。
总得分是0分。
所以,代码运行后应该输出:

4.优先级问题
问题:
如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高
输入:

输出:

解决方法:

  • 添加逻辑判断
if ((answer == null && title.isDeleted())||(answer == null && nonExistentQuestions.contains(title.getTitleID()))||(answer == null && nonExistentQuestions.contains(title.getTitleID())&&title.isDeleted())) {
                System.out.println("answer is null");
            } 

结果:

四.改进建议

7-5 答题判题程序-1:

1. 输入格式的检查
问题:

  • 如果输入格式不符合要求,可能会导致解析失败,并抛出异常,如 NumberFormatExceptionArrayIndexOutOfBoundsException

改进建议:

  • 增加输入数据的检查,在解析题目或答案时进行错误处理。
  • 使用 try-catch 捕获异常,或者对输入数据提前进行验证。

2. 防止重复题目ID
问题:

  • 如果题目ID重复,后添加的题目会覆盖之前的题目。

改进建议:

  • 检查题目ID是否重复,并在添加时给出提示。

3. 用户答案与题目数量不匹配时的处理
问题:

  • 如果用户提交的答案数量与题目数量不一致,程序会抛出 IndexOutOfBoundsException

改进建议:

  • 检查用户提交的答案数量是否匹配,给出适当的提示。

4. 去除答案前缀的优化
问题:

  • 当前通过 replace("#A:", "") 去除前缀,但多个 #A: 可能造成问题。

改进建议:

  • 使用正则表达式准确匹配并去除前缀。

5. 标准答案比较逻辑的改进
问题:

  • 只使用 equalsIgnoreCase 进行比较,未去除多余空格。

改进建议:

  • 在比较前去除答案中的多余空格,以提高容错性。

6. 简化代码结构,提高可读性
问题:

  • 部分代码如 saveAnswers 中存在冗余逻辑,可以简化。

改进建议:

  • titleID的计算移出循环,避免重复计算。
  • 使用 for-each 循环提高代码可读性。

7. 考虑异常处理的完整性
问题:

  • 代码中部分地方没有考虑潜在的异常(如解析整数时的 NumberFormatException)。

改进建议:

  • 使用 try-catch 结构捕获异常,并给予用户友好的错误信息。

7-4 答题判题程序-2:

  1. 代码结构改进

问题:主方法 (main 方法) 中逻辑较长且混杂了不同的解析操作,影响可读性。

改进建议:可以将题目解析试卷解析答案解析封装成独立方法,降低 main 方法的复杂度,使代码更具模块化和易读性。

  1. 输入格式校验和错误处理

问题:代码假定输入格式是完全正确的,缺乏对输入格式错误的防御性检查。

改进建议:在解析 titlePatterntestPatternanswerPattern 时,增加对输入格式的验证,并在输入不符合预期时输出友好的错误信息。

  1. 字符串分割逻辑的改进

问题:在处理用户答案时,通过 split("\\s+#A:") 提取答案部分,但该方法可能会产生多余的空白项。

改进建议:可以直接使用 replaceFirst 去除前缀,并对答案数组提前进行去除空格操作,保证答案提取准确。

  1. 试卷总分警告的改进

问题:如果试卷总分不等于 100,程序输出警告,但未中断或进一步处理。

改进建议:可以添加一个标志记录不符合要求的试卷,并在全部解析后统一输出警告,方便查看。

  1. 回答解析与评分部分优化

问题:在 judgeAnswers 方法中,逐个解析题目和答案并记录得分,但如果答案数量少于题目数量,则程序会自动填入 false,可能会影响数据一致性。

改进建议:可以在用户**与题目数量不匹配时给出错误提示,确保用户输入与系统期望一致。

  1. 改进输出格式

问题:输出格式在某些情况下不够清晰,例如在回答和评分时没有详细标注问题编号和**。

改进建议:在输出时可以添加题目编号、**及其判定结果,使输出内容更具可读性。

  1. 提高代码的可复用性和维护性

问题:当前程序的某些方法较长且逻辑集中在一起,增加了代码的复杂度和未来维护的难度。

改进建议:将重复的分数计算逻辑提取为一个工具方法,简化主逻辑代码的复杂度。

  1. 加强代码的异常处理

问题:代码没有处理可能的异常(如 NumberFormatException),当输入不合法时会导致程序中断。

改进建议:使用 try-catch 结构包裹解析部分,并为用户提供更友好的错误提示信息。

7-3 答题判题程序-3:

  1. 重构数据结构
  • 冗余数据减少orderToTitleIDtitlesscores都包含相似的映射关系,可以使用单一的数据结构(如Map<Integer, Pair<Title, Integer>>)替代,以减少不必要的存储和数据同步问题。
  • 嵌套数据访问的优化:在AnswerSheet中可以通过创建List<AnswerResult>结构来存储每道题目的判断结果和得分状态。这种结构有助于将判断结果、题目信息和得分绑定在一起,减少后续的数据查找和同步成本。
  1. 优化判分逻辑
  • 判断和计分方法合并judgeAnswersprintAnswersAndJudgeResults中重复了答题判分的逻辑。可以将它们合并,使judgeAnswers方法在完成题目判断时,直接生成每个题目的结果对象(如AnswerResult),并在printAnswersAndJudgeResults中直接遍历这些结果对象输出。
  • 将非存在题目的判断提前:在构造AnswerSheet时直接处理不存在的题目,可以减少每次判分中的重复判断逻辑,提高效率。
  1. 输入格式解析的改进
  • 分离格式校验和业务逻辑:当前的输入解析、校验和业务处理都写在同一个Main方法中。建议使用专门的解析类(如InputParser),将不同的匹配逻辑封装在方法中。这样不仅使代码更易读、易维护,而且在后续增加新格式或逻辑时更易扩展。
  • 异常处理:在输入解析和答案解析时,使用了基本的异常处理机制。可以针对不同的格式错误添加详细的错误信息,并指明错误行,便于用户调试和查错。
  1. 提高可读性
  • 方法名和变量名优化:例如,printAnswersAndJudgeResults可以更具语义化地命名为displayAnswerEvaluationjudgeresults可以改为answerResults或类似更直观的名称。
  • 移除硬编码输出:例如在judgeAnswers中的System.out.println(e.getMessage());,可以定义常量或消息格式化工具,以便在多语言环境下复用代码。
  1. 改进用户反馈
  • 更清晰的反馈信息:在处理学生答案时,若发现不存在的学生,可以提供更具体的信息。例如:System.out.println("Student ID " + studentID + " not found in the system.");
  • 增加完整的答题反馈:目前,打印反馈中包含每个答案的对错标记,但未标注得分。可以增加对每个答案的得分输出,帮助用户更直观地了解答题得分情况。
  1. 增强代码鲁棒性
  • 加强边界检查:在printScores中,judgeresults.get(order - 1)的操作可能会导致索引越界错误,可以增加边界检查,或在judgeAnswers中提前填充judgeresults确保数量一致。
  • 输入值校验:对于testIDstudentID等输入值,当前代码未对输入的合法性进行验证。可以在解析时添加有效性校验,避免非法输入导致异常崩溃。

五.总结

通过三次题目集的练习,我学会了如何通过方法来实现类的功能。我实现了多个类,将不同的逻辑封装在各自的类中,实现了职责分离,并通过构造函数和方法来封装数据和行为。这加深了我对类和对象的理解。我使用了Map、List和Set等集合类来存储和管理数据。通过TreeMap和LinkedHashMap来保持数据的顺序和唯一性,这让我对Java集合框架有了更深入的理解。我了解了如何将数据组织成更复杂的结构,例如将题目与分数关联,如何在答卷中记录用户答案及其判断结果。使用正则表达式解析输入数据,这让我认识到正则表达式在数据处理中的强大能力,能够有效地提取和验证字符串格式。我学会了如何从标准输入流中读取数据,并处理多行输入。这是处理用户输入的一种常见方式。理解了如何将复杂的逻辑分解成多个方法和类,使得代码更加模块化和可维护。我学会了如何处理异常情况,比如输入格式错误或找不到题目等。
需要进一步学习及研究的地方:虽然我在代码中实现了一些基本的面向对象原则,但我希望进一步学习设计模式,以提高代码的可重用性和可维护性。虽然已实现了一定的正则表达式解析,
但在复杂格式的解析和处理上仍需提升。例如,在解析题目和答案格式时,代码对于多层嵌套结构和错误处理的支持有限,可以研究更复杂的正则表达式或自定义解析器来提高精度。代码中对错误处理和异常报告的支持有待提升。未来学习嵌套的数据结构(如Map<Integer, List>)以及泛型的高级用法,帮助代码适应更复杂的数据场景。
对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见:多留点时间写PTA或者开放之前的PTA。