22207203-陈思思

题目集1~3的总结

  1. 前言
  2. 第1次题目集
  3. 知识点:第一次的题目难度不高,而且给了明确要求,还给出了分类的建议,很详细,跟着写加一些自己的逻辑就能够写好。主要掌握类的运用和理清类与类之间的关系。其次就是对输入信息的提取与分类,这个使用正则表达式可以比较准确的解决问题。
  4. 题量:题量较少,可以包括大部分的提交判定程序,输入输出比较简单明了。
  5. 难度:难度适中,主要考察基本的数据处理能力和逻辑判断能力。

这其中我主要遇到的一个问题是最后的一个例题,会在下面进行分析。

  1. 第2次题目集
  2. 知识点:更复杂的数据结构,在现有的完整程序中增添新类。增添了异常处理,在第1次的基础上更加细化了输入信息的提取与分类,以及对信息的判断与输出。
  3. 题量:题目集扩展了对多张试卷的支持,并且题目与试卷信息可能混合输入,增加了输入处理的复杂度。
  4. 难度:难度上升,增加了分值的累加和异常情况的处理,还增添了答卷类。
  5. 第3次题目集
  6. 知识点:进一步扩展了功能,加入了学生信息管理和题目删除功能。异常处理的要求进一步升级,还需增添题目删除后的逻辑处理。
  7. 题量:题目集更加贴近实际应用,不仅处理多张试卷,还要处理多名学生的答题情况,并支持题目删除。
  8. 难度:难度上升的很大,对系统的灵活性要求很高,输入的信息多,处理信息的要求也多,很容易漏处理或者达不到同时处理好的效果。

注意:以下的各项分析都是各个题目集中的最后一题,即答题判题程序1~3。

  1. 设计与分析

三次题目集的最后一题基本都是这个框架,没有进行大的改进,只是添加了一些内部的方法,就不一一画出来了。

  1. 类图

  2. SourseMonitor的检测

  答题判题1:

  答题判题2:

  

 

  答题判题3:

 

 

  1. 踩坑心得
  2. 第1次题目
  3. 对于题目内容的提取(最后一题的分析)
  4. 修改前的题目提取:

//提取输入的题目内容

    public void extractQuestions(String input) {

        //String input = reader.readInput();

        Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.*?) #A:(.*)");

        Matcher matcher = pattern.matcher(input);

        while (matcher.find()) {

            int number = Integer.parseInt(matcher.group(1));

            String content = matcher.group(2).trim();

            String answer = matcher.group(3).trim();

            Question q = new Question(number, content, answer);

            testPaper.addQuestion(q);

        }

    }

  1. 测试问题

输入:

1

#N: 1 #Q: 5 +5= #A:10

#A:10

end

结果与分析:提交显示非零返回

因为输入的题目信息中#N: 1 #Q: 5 +5= #A:10的空格存在位置,与我所设置的正则表达式不符合,所以正则表达式无法判断,就会导致非零返回。

修改提要:这种情况应该是的#N:后面的空格、题号与下一个#之间的空格、题目内容与:之间的空格都能够可选择的存在,以及题目内容与下一个#之间的空格都可以可选的存在,也就是可有可无,都能够正确的提取信息。

  1. 修改:

   Pattern pattern = Pattern.compile("#N:(?: )?(\\d+)(?: )?#Q:(.*?) #A:(.*)");

   Matcher matcher = pattern.matcher(input);

(?: )?即代表可选空格

  1. 对于用户答案的存储
  2. 修改前的答案提取:

// 从输入读取器读取用户的答案

    public void readAnswersFromInput(String input) {

        // 使用 \n 分割输入字符串,按行处理

        String[] lines = input.split("\n");

        for (String line : lines) {

            if (line.startsWith("#A:")) {

                // 使用正则表达式匹配并提取答案

                Pattern pattern = Pattern.compile("#A:(\\d+)");

                Matcher matcher = pattern.matcher(line);

                int index = 1; // 用于跟踪题号

                while (matcher.find()) {

                    // 提取匹配到的答案

                    String answer = matcher.group(1).trim();

                    // 保存答案

                    saveAnswer(index, answer);

                    index++;

                }

            } else if (line.equalsIgnoreCase("end")) {

                break;

            }

        }

    }

  1. 测试问题

输入:

1

#N:1 #Q: The starting point of the Long March is #A:ruijin

#A:ruijin

end

结果与分析:提交结果与预期结果不符合

因为设置的正则表达式中#A:后面只能有\\d+,即各种数字,而目前输入的内容中答案内容是字符串不是数字,导致无法正确的提取输入并判断。

修改提要:能够捕获#A:后面跟随的答案,直到遇到另一个#符号,而不是仅仅匹配数字。这允许解析更复杂的答案输入,不仅限于数字。

  1. 修改:

// 使用正则表达式匹配并提取答案

                Pattern pattern = Pattern.compile("#A:([^#]+)");

                Matcher matcher = pattern.matcher(line);

  1. 第2次题目
  2. 乱序输入+分值不足100+两份答卷+无效的试卷号(最后一题)
  3. 修改前的分析输出(图片非代码!!!):

  1. 测试问题:

输入:

#N:3 #Q:3+2= #A:5

#N:2 #Q:2+2= #A:4

#T:1 3-7 2-6

#S:3 #A:5 #A:4

end

结果与分析:提交结果与实际结果不符合

修改提要:仔细检查并分析代码后发现是因为The的T写成了t,所以报错。

  1. 修改:

   if (testPaper == null) {

                System.out.println("The test paper number does not exist");

                continue;

            }

将t 换成 T 。

  1. 用户答案为空的情况
  2. 修改前:

修改前的gradeAnswers 方法:

String userAnswer = (answers.size() > i) ? answers.get(i) : "answer is null";

boolean isCorrect = q != null && q.isCorrect(userAnswer);

修改前的答案输出的print 方法:

if (q != null) {

System.out.println(q.getContent() + "~" + userAnswer + "~" + gradingResults.get(i));

} else {

System.out.println("answer is null");

}

  1. 测试问题

输入:

#N:3 #Q:3+2= #A:5

#N:2 #Q:2+2= #A:4

#T:1 3-7 2-6

#S:1 #A:5 #A:22

#N:1 #Q:1+1= #A:2

#T:2 2-5 1-3 3-2

#S:2 #A:5 #A:4

end

结果与分析:answer is null出现的位置不对,而且当答案为空的时候,不需要再输出完整的题目与判断,只需要输出answer is null。

分析代码在这种情况下,如果用户答案不存在,则 userAnswer 会被设置为 "answer is null",这可能导致在比较时出现错误。存在直接输出题目和用户答案的情况,甚至在用户答案为空的情况下输出了题目信息。

修改提要:userAnswer 被设置为 null,且在验证答案的正确性时需要先检查 userAnswer 是否为 null。此修改增加了代码的健壮性,可以避免错误的比较。增加了对用户答案是否为空的判断,只有在用户答案存在的情况下才输出题目信息。这避免了在用户未回答的情况下仍然输出题目信息,提升了程序的用户友好性。

  1. 修改:

gradeAnswers 方法修改:

String userAnswer = (answers.size() > i) ? answers.get(i) : null;

boolean isCorrect = (userAnswer != null && q != null && q.isCorrect(userAnswer));

答案输出print方法的修改:

if (userAnswer != null) {

if (q != null) {

System.out.println(q.getContent() + "~" + userAnswer + "~" + gradingResults.get(i));

}

} else {

System.out.println("answer is null");

}

  1. 第3次题目

这个最近我印象也最深,在作业截止之前,我仍然没有得到满分,但这个时候我已经意识到了,我的错误在哪里,当输入的答卷中只有#S:和对应的试卷号,没有输入#A和对应的答案时,我的代码限制的太死了,没有检测到#A就不会进行答案分析与存储,这个就导致当输入的答卷中没有任何答案的时候,我的代码不会输出答案判断与最后的分数总结,真的很让人遗憾,第3次作业也是我3次作业中唯一没有满分的题目集,让我意难平。相关的输入过于自由,也就导致我的判断体系得十分健壮和完善,很多时候修改好了一个错误却导致另一个正确的情况变成错误答案。所以,写代码之前的分析十分重要,先分析要分成几个类,每个类的作用是什么,类与类之间具有什么关系,然后先实现各个类的基本功能,之后再根据题目的异常报错要求,设计一个能够自洽完善的逻辑,这个过程要十分细致,这其中正则表达式对输入的提取就十分重要了,要写出符合题目要求的正确的正则表达式。然后思考,提取出来的内容怎么存,要不要存,存进去了怎么取,取的时候有没有内容,各种情况下应该要怎么做。下面我就不啰嗦了,直接写最后一题的情况与分析。

processInput 方法中的修改

修改前:

Matcher answerMatcher = Pattern.compile("#S:(\\d+) (\\S+) #A:(.*)").matcher(input);

修改后:

Matcher answerMatcher = Pattern.compile("#S:(\\d+) (\\S+) (.*)").matcher(input);

测试样例(错误情况)(不在测试样例,不好截测试图):

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

输入:

#N:1 #Q:1+1= #A:2

#T:1 3-8

#X:20201103 Tom-20201104 Jack-20201105 Www

#S:1 20201103

end

预期输出:

alert: full score of test paper1 is not 100 points

answer is null

20201103 Tom: 0~0

我的实际输出:

分析:

修改了正则表达式,去掉了 #A: 的部分。这样改动使得答案项可以被更加灵活地解析,因为答案的部分的前缀 #A: 不再是必须的;这意味着可以接受任何格式的答案输入,增强了系统的灵活性和鲁棒性。

  1. 改进建议

对于题目集3的最后一题答题判题程序3的内容,我认为题目中的要求实在多,看起来很费劲,需要反复地上下滑动来确定要求,而且在一个完整的代码中添加新类,重新分配一下分工真的有点难度。希望可以将重点放在类的功能划分与类与类之间的关系上面,这次的题目集,越到后面我越感觉好像主要考核的是输入信息的划分与提取,并对信息进行存储与分析,最后按照格式来输出。

但其中确实又考察到了类,可输入与输出实在是太让人疲惫了,下次出题建议多加点内部的功能,不要再困在输入与输出了,我要做吐了,看的真的头晕,想写纸上也不好总结归纳。

我的代码内容,用到的几个类中,因为最初的不熟悉,所以功能划分不太好,导致有的类干很多事情,有的类只干一件事,但又不好改动,所以对我自己的代码改进建议与总结是,下次一定要仔仔细细的看完题目,然后合理的划分好功能,再去写代码,不然后面太累了,中途修改又耗时,所以最好是前面的地基打好,后面好做事。

  1. 总结

在完成题目集1至3的过程中,我深刻体会到了编程实践的挑战与乐趣。从最初的类与对象的基本运用,到复杂数据结构的处理,再到异常情况的全面考虑,我的编程能力得到了显著提升。

在第一次题目集中,我主要学习了如何运用类来组织代码,并理解了类与类之间的关系。通过对输入信息的提取与分类,我学会了使用正则表达式来精确匹配和处理数据。这次题目集让我初步掌握了编程的基本技巧,为后续的学习打下了坚实基础。

第二次题目集在第一次的基础上增加了难度,我学习了如何在现有程序中添加新类,并处理更复杂的数据结构。异常处理机制的引入也让我学会了如何更好地应对程序运行中的错误情况。这次题目集锻炼了我的代码扩展能力和错误处理能力。

第三次题目集则更加贴近实际应用,我不仅要处理多张试卷和多名学生的答题情况,还要支持题目的删除功能。这次题目集对系统的灵活性要求很高,我深刻体会到了编程中细节的重要性。在处理输入信息时,我必须确保正则表达式的准确性,以避免因细微差别而导致的错误。同时,我也学会了如何更好地设计类的结构和功能,以提高代码的可读性和可维护性。

在完成这些题目集的过程中,我也遇到了一些挑战。例如,在处理输入信息时,我有时会因为正则表达式的不准确而导致程序无法正确运行。此外,在设计类的结构和功能时,我也有时会因为对题目要求的理解不够深入而导致代码设计不合理。这些问题让我意识到,编程不仅需要掌握基本技巧,还需要具备细致入微的观察力和深入思考的能力。

为了进一步提高自己的编程能力,我需要加强对正则表达式的理解和运用,以更准确地处理各种输入信息。同时,我也需要加强对面向对象编程思想的理解和实践,以更好地设计类的结构和功能。此外,我还需要加强对异常处理机制的学习和运用,以提高程序的健壮性和稳定性。

对于教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见,我认为:

1.教师在讲解课程时应注重理论与实践的结合,通过具体案例来帮助学生理解抽象概念。

2.作业和实验应更加贴近实际应用,以提高学生的编程实践能力和解决问题的能力。

3.课上应增加互动环节,鼓励学生提问和讨论,以激发学生的学习兴趣和积极性。

4.课下应组织更多的编程实践活动和小组讨论,以帮助学生巩固所学知识并拓展视野。

总之,通过完成题目集1至3,我不仅提高了自己的编程能力,还学会了如何更好地应对挑战和解决问题。在未来的学习中,我将继续努力提升自己的编程水平,并积极参与各种编程实践活动,以更好地适应未来的职业发展需求。

posted @   blog666  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示