《第二次博客》
一.答题判题程序-4
-
前言:
1>.代码主要功能:
主函数的输入部分: 解析输入:使用 Scanner 对象从控制台读取输入,并解析以特定格式开头的文本行。 创建题目:解析题目相关信息(题号、内容、答案),并将其存储在 Question 对象中,然后添 加到题目列表中。 创建试卷:解析试卷相关信息(试卷编号、题号与分数对应关系),并将其存储在 TestPaper 对 象中,然后添加到试卷 Map 中。 创建学生答卷:解析学生答卷相关信息(答卷编号、学号、题号与答案对应关系),并将其存储在 AnswerSheet 对象中,然后添加到学生答卷 Map 中。 学生信息管理:解析学生信息(学号、姓名对应关系),并将其存储在学生 Map 中。 删除题目:解析要删除的题目编号,并将其存储在删除列表中。 这段代码用于管理题目、试卷、学生答卷和学生信息,并提供了基本的解析和存储功能。 主函数的输出部分: for (int paperNumber : testPapers.keySet()) { TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷 int totalScore = 0;//总分 for(NumberScore numberScore :testPaper.getNumberScores()) { totalScore += numberScore.getScore();//求试卷总分 } if (totalScore != 100) { System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points"); }//不是100则输出 } 这段代码的功能是遍历一个包含测试试卷的映射,然后计算每张试卷的总分,并检查是否达到满 分(100分)。如果某张试卷的总分不是100分,则输出相应的信息。 Map<String, List<AnswerSheet>> answerSheets = new TreeMap<>(answerSheetss); // 根据学号从小到大排序(学号的优先级大)这里的程序正确排序正常 for(String studentID : answerSheets.keySet()) { List<AnswerSheet> AnswerSheets = answerSheets.get(studentID); //根据答卷号排序,在这个学生list库, int nn = AnswerSheets.size(); for (int i = 0; i < nn - 1; i++) { for (int j = 0; j < nn - i - 1; j++) { if (AnswerSheets.get(j).sheetNumber > AnswerSheets.get(j + 1).sheetNumber) { // 交换元素 AnswerSheet temp = AnswerSheets.get(j); AnswerSheets.set(j, AnswerSheets.get(j + 1)); AnswerSheets.set(j + 1, temp); } } } 这段代码的功能是对包含学生答卷的映射进行遍历,并对每个学生的答卷列表按照答卷号从小到大 进行排序。 然后就再遍历试卷问题列表,并检查学生的答案是否正确。它会逐个比较学生答案和标准答案,然 后输出相应的结果,包括答案是否完全正确、部分正确或者错误,并在需要时输出相关提示信息, 如学生答案为null或者问题无效。 //打印1+1=~5~false形式在之后就是输出最后每个学生的总 得分情况根据学生的答题情况计算总分,并输出每道题的得分情况。它首先从一个名为students 的映射中根据学号获取学生姓名,然后遍历题目列表和学生答案列表,逐题比对学生答案和标准答 案,计算得分,并根据得分情况输出结果。//打印 打印20201103Tom: 0 0~0形式。
2>.主要知识点:
在输入部分主要设计的知识点有一下: 主要涉及以下知识点: 输入输出流处理:使用Scanner从标准输入读取数据。 集合类的使用:使用ArrayList、HashMap、List等集合类来存储题目、试卷、答卷等信息。 正则表达式:使用正则表达式来匹配特定格式的输入行。 字符串操作:对输入的字符串进行切割、去除空格等操作。 自定义类的使用:定义了Question、TestPaper、AnswerSheet等自定义类,并对其进行实例化 和操作。流程控制:使用while循环和条件判断语句来控制程序流程。 错误处理:对输入行的格式进行检查,如果格式不符合要求,则输出错误信息。 在输出部分涉及到的一些知识点: 数据结构和集合操作: 使用了Map和List来存储答卷信息,并通过迭代和条件判断对答卷进行处理和输出。 排序算法:使用了冒泡排序算法对每个学生的答卷进行按答卷号排序。 字符串处理:对学生和标准答案进行了字符串分割操作,以便比较和判断正确性。 条件语句和循环结构:使用了条件语句和循环结构来实现对答案的检查和输出。 逻辑判断:根据学生答案和标准答案的对比,判断答案的正确性和部分正确性。 错误处理:对于无效的问题编号,进行了相应的错误处理输出。 Java基础知识:涉及到了Java集合操作、字符串操作、条件语句、循环结构等基础知识。 程序设计思想:体现了对问题的分解、逻辑处理、错误处理等程序设计思想。
3>.题目的题量:
整体来说本次的题量还是较大的需要编写较多的函数对与主函数部分进行简化,使得代码的逻辑通 顺易懂
4>.题目难度:
本次的题目难度较大,由于是第四次对于代码的迭代所以整个代码比较隆长,但是如果是第三次迭 代的较为完整的话这题的难度也不是很大,不过在迭代过程中要理清逻辑代码的进行顺序
-
设计与分析:
在本次的题目设计中主要是设计了三个类, Question问题类 TestPaper试卷类 AnswerSheet答 卷类和NumberScore题目分数类,而在试卷类中初始化了 List<NumberScore> NumberScores; 用于存储试卷里的题目编号和题目编号对应的分数,用于后续的评分计算 在主函数中有以下存储集合 List<Question> questions = new ArrayList<>();//题目的数组 Map<Integer, TestPaper> testPapers = new HashMap<>();//试卷编号——试卷 Map<String, List<AnswerSheet>> answerSheetss = new HashMap<>();//学号——学生多答卷 Map<String, String> students = new HashMap<>();//学号——姓名 List<Integer> deletes = new ArrayList<>();//删除的题目 使用了三个HashMap 和 两个List集合存储相关信息 由SourceMonitor软件分析数据如下:
本次设计的类图关系图如下:
-
采坑心得:
1.在这次大作业中有很多测试点都是与正则表达式有关系的,主要怕是看 输入的正确与否,所有就需要较多的正则表达式去检索这个输如字符串 2.在我本次的作业中变量使用的名字不太清晰明了 3.还有很多注释没有写出来,导致写了下面的忘了上面的 4.本次的的代码设计的不够完善,导致我代码较为隆长,循环嵌套太多, 调试的时候很不舒服
-
改进建议
部分代码逻辑重复,应考虑封装成方法或者优化逻辑结构。 对于一些可能发生异常的地方,缺乏异常处理机制,可能导致程序运行时 出错。注释不足:虽然代码中有一些注释,但是注释不够清晰详细,无法 完整地解释代码的功能和逻辑。数据结构选择可能不合适:某些情况下选 择的数据结构可能不够高效或者不够合适,导致性能下降。 使用 equals 方法比较字符串相等性:在 Java 中,应该使用 equals 方法来比较字符串的内容是否相等,而不是使用 ==。因此,将 if(answer=="answer is null") 改为 if(answer.equals("answer is null"))。优化循环:可以优化代码中的循环,在这里遍历 paperquestion 集合时可以使用增强的 for 循环,替换当前的 for 循 环。简化条件判断:可以简化条件判断的逻辑,如在判断是否存在题目编 号大于等于 100 的情况时,可以使用 else if(question.getNumber() >= 100)。减少嵌套:减少多层嵌套的代码结构,可以通过提取方法或重新 组织逻辑来减少代码的层级深度和复杂度。
二.家居强电电路模拟程序-1
-
前言:
1>.代码主要功能:
在输入部分的功能:用户输入以 “[” 开头的指令来创建不同类型的设备,指令格式为"[ 类型 设备 名称 ]",根据类型不同创建开关、齿轮速度调节器、连续速度调节器、白炽灯、荧光灯、吊扇等不 同类型的设备,并 将其添加到设备列表中。用户输入以 “#” 开头的指令来对设备进行状态调节操 作,指令格式为"# 类型 设备名称 参数",根据类型不同执行不同的操作,包括切换开关状态、调 分档调速器的状态、设置连续调节器挡位等。程序通过不断读取用户输入来实现对设备的创建和控操 作,直到用户输入"end"结束程序运行, 允许用户创建不同类型的设备并对这些设备进行状态控制 操作。 在输出部分:输出部分主要设计的功能是电压的传递,也就是电压的赋值操作 检查设备列表中设备数量,并针对不同数量的设备执行不同的操作。 如果只有1个设备,直接设置电压为220V。 如果只有2个设备,先检查第一个设备是否是某种控制器,如果是,获取其输出电压并设置给第二个 设备。 如果设备数量多于2个,则需要更复杂的逻辑来处理开关状态和电压传递。 根据设备类型和开关状态,设置设备的电压值。例如,如果设备是开关并且是闭合的,则将电压设置 为220V,否则设置为0V。 对于超过2个设备的场景,代码会先对所有开关设备进行排序,然后根据开关的状态来决定是否给其 他设备供电。 输出设备的状态,包括开关的状态和不同类型设备的输出信息(例如速度、亮度等)。
2>.主要知识点:
1.通过 Scanner 和 System.in 来接收用户的输入,实现交互式输入。 2.字符串处理:使用了字符串操作方法,如 startsWith、substring、split、charAt 等来处理 用户输入的字符串。 3.多态:在往 devices 列表中添加设备对象时,利用多态实现了将不同子类对象当作父类对象来处 理。 4.类继承与对象实例化:定义了 Device 类及其子类 Switch、GearSpeedController、 ContinuousSpeedController、IncandescentLamp、FluorescentLamp、CeilingFan,并根据 用户输入的不同类型来实例化相应的子类对象。 5.通过对 devices 中的设备进行遍历查找及强制类型转换,实现了根据用户输入操作来对设备进行 状态控制。 6.使用了 switch-case 语句块进行根据不同条件执行不同的操作。 7.采用了面向对象设计原则,如单一职责原则、开闭原则,使得代码结构清晰、易于拓展和维护。 8.遍历循环:使用了 for 循环对设备列表进行遍历操作。
3>.题目的题量:
本次的题量由于是第一次迭代,题量还不算大只需要稍微设计好类,使用类之间的函数 在主函数中由于电器的复杂度不是很高只是串联
4>.题目难度:
本题的题目难度不大,只要设计好类,即可简化代码的复杂性如果单独设计设备类和设备子类的话还 不太能梳理好代码的逻辑,在本题中设计好类之间的的关系和处理好类与类之间的相互调用关系就可 以大大减小代码的量度,简化代码
-
设计与分析:
由SourceMonitor软件分析数据如下:
本次设计的类图关系图如下:
-
采坑心得:
在第二次的迭代过程之中,由于题目的电路类型升级到了串联和并联一起处理,和我第一次没有设计 好串联类,导致我在第二次的作业中遇到了较为麻烦的改动,重新设计好了类串联类和并连类 所以在第一次的迭代之中我们应该以题目的整体要求设计好类,并不是觉得没这个必要就可以不设计 这个类,如果是这样的话在后续的迭代过程之中我们的之前的代码代码就做不好迭代,所以本次大作 业收获到的是这个较为深刻,还有在我排序的时候可以使用接口对类里面的参数进行排序
-
改进建议
输入部分: 在处理输入时,没有对输入做合法性检查,可能会导致程序在输入不符合预期格式时出错。建议添加 输入检查机制,避免因为不合法输入导致程序崩溃。 可以将相似的操作抽取为方法,减少代码的重复性。 可以将设备的创建和设备状态调节的逻辑分离成不同的方法,提高代码的可读性和可维护性。 建议使用更具有语义化的变量名和方法名,提高代码的可读性。 在设备状态调节的部分,通过HashMap存储设备对象可以提高查找效率,减少遍历查找的时间复度。 输出部分: 将注释中的设备代号更改为更具有描述性的名称,提高可读性和可维护性。 可以考虑封装一些逻辑复杂的部分为独立的方法,以提高代码的模块化和可读性。 如果可能的话,可以使用switch-case语句来替代多层的if-else结构,使得代码更加简洁。 在排序Ks列表时,可以考虑使用Collections.sort(Ks, Comparator)方法,使排序操作更加简洁 高效。 可以使用增强for循环来遍历设备列表,使代码更加简洁。 注意代码中的硬编码,如220.0等数字,可以考虑将其提取为常量,提高可维护性。 在打印输出时,可以考虑使用String.format()方法来格式化输出,使得输出更加规范和易读。
三.家居强电电路模拟程序-2
源码如下:
点击查看代码
-
前言:
1>.代码主要功能:
基本设备类和设备子类: 实现了一个设备控制系统的基本框架,包括了设备类(Device)、控制设备类 (ControlDevice)、开关类(Switch)、分档调速器类(GearSpeedController)、连续调速器 类 (ContinuousSpeedController)、受控设备类(ControlledDevice)以及多种具体的受控设备 类 (如白炽灯、日光灯、吊扇、落地扇等)。 其中,设备类包括了设备的基本信息和属性,并且设备类为其他类提供了基本的属性和方法继承; 控制设备类是设备类的子类,用来实现具体的设备控制逻辑;开关类实现了开关设备的功能,可以 切换开关状态并输出相应电压;分档调速器类实现了分档调速的功能,可以根据档位调整输出电 压;连续调速器类实现了连续调速的功能,可以根据速度因子调整输出电压;受控设备类是设备类 的子类,用来实现具体的受控设备的输出计算逻辑;最后,具体的受控设备类(如白炽灯、日光 灯、吊扇、落地扇)分别实现了自身的输出计算逻辑,根据不同的电势差计算出相应的输出值。 其次是并联和串联类:这段代码主要是实现了电路中串联电路和并联电路的计算功能。其中 Series 类表示串联电路,包括添加设备、计算总电阻、判断电路状态(闭合或断开)、计算设备 之间的电压差等功能;Parallel 类表示并联电路,包括添加串联电路、计算总电阻、设置电压差 等功能在 Series 类中,通过 addDevices 方法可以向串联电路中添加设备并计算总电阻,通过 judgeCstate 方法判断串联电路中各设备的状态,通过 devicesV1_V2 方法计算各设备的电压 差。而在 Parallel 类中,通过 addCDevices 方法向并联电路中添加串联电路并计算总电阻, 通过 devicesV1_V2 方法设置并联电路中各串联电路的电压差。 对于电压的计算部分:遍历第一系列(series1)中的电器设备,查找名称为"M1"的设备,将该设 备的电阻设置为并联电阻的值,并重新给"M1"设备赋予这个电阻值。 根据第一个电路设备的类型进行判断,计算总电路的电压: 如果是开关设备(Switch),根据开关状态设置电压为220.0或0.0。 如果是齿轮速度控制器(GearSpeedController),获取其输出电压。 如果是连续速度控制器(ContinuousSpeedController),获取其输出电压。 否则将电压设定为220.0。 将计算得到的电压赋值给总电路,并计算总电路中各个电器的电压。 遍历总电路中的设备,如果设备名称是"M1",则将其电压赋值给并联电路。 对并联电路中的每个串联(Series)进行计算各个电器的电压。 最后使用排序的代码对于个个设备的类型和编号进行排序输出个个设备的状态
2>.主要知识点:
类的设计过程到以下知识点: 面向对象编程:代码中通过定义类和对象的方式来实现功能,包括设备类、控制设备类、受控设备 类等。 继承与多态:使用了类的继承,如控制设备类继承自设备类,受控设备类继承自设备类,并实现了 多态性。 成员变量与方法:类中定义了成员变量和方法,如设备的名称、编号、电压、电阻等属性和设置、 获取这些属性的方法。 抽象类和接口:在代码中展示了抽象类(ControlDevice)和方法(adjust()、 calculateOutput())作为抽象方法的使用。 条件判断和计算:在受控设备类中根据不同条件计算输出值。 数组的使用:在档位调节器类中使用了数组来存储不同档位的系数。 方法的重写:在受控设备类中重写了calculateOutput()方法。 实例化对象:代码中实例化了各种设备,如白炽灯、日光灯、吊扇、落地扇等。 对象属性封装:通过设置私有属性和公共方法来实现对象属性的封装。 在主函数部分: Java 中的面向对象编程:定义了 Device、Switch、GearSpeedController、 ContinuousSpeedController、Series 等类,并在代码中创建对象、调用对象的方法和属性。 Java 中的集合操作:使用了 ArrayList 对象 series1.devices 进行遍历操作。 条件语句:通过 if-else 语句判断设备的类型(Switch、GearSpeedController、 ContinuousSpeedController)以及状态,进而计算电压。 方法调用:调用对象的方法,比如 series1.Mresistance(parallel.BR())、 device.setResistance(parallel.BR())、series1.setV1_V2(V)、 series1.devicesV1_V2()、parallel.setseriesV() 等。 循环操作:使用 for 循环遍历设备列表 series1.devices,对符合条件的设备进行处理;同时 也对并联电路的子串联进行循环处理。 逻辑操作:根据设备的类型,状态和属性计算电路的电压和电阻值。
3>.题目的题量:
本次的题目的题量较为一般不是很多也不是很少,在类的设计过程之中含有较多的方法所有导致题目
的题量会较大一点,但是方法都在之中设计好了,主要在主函数之中调用,所以主函数的内容较为简
短 明了所以整体的题量一般不是很多,其实我的代码还可以在进行输出反面的简化,在下次的迭代之
中我会进行更加简单的简化我的代码4>.题目难度:
本题的难度在于类的设计之中,主要是串联和并联类,串联类的第一个对象是主电路,主电路作为串 联类的一个对象,并联里的子串联类也是串联类的对联,并联类是由多个串联类组成的类,在并联类 之中含有串联类的数组List<Series> series,在串联类中含有多个设备类,含有List<Device> d evices 数组,存放串联中的设备,在类的设计之中,主要是函数中的个个类之间的调用的时候较为 麻烦难以理顺。
-
设计与分析:
由SourceMonitor软件分析数据如下:
本次设计的类图关系图如下:
-
采坑心得:
在 Device 类中的构造函数中,提取 name 中的编号的方法可能存在潜在问题。应该考虑一些边缘 情况,例如 name 是否符合预期的命名规则,以及编号提取的逻辑是否稳健。 在 ControlledDevice 类和其子类中的 calculateOutput 方法中,应该考虑更复杂的输出计算 逻辑,确保计算的准确性。当前的计算方法较为简单,可能无法满足实际需求。 在 GearSpeedController 类和 ContinuousSpeedController 类中,对于调节档位和速度比例 的操作,应该添加更多的边界条件和约束,以确保在调节时不会超出合理范围导致错误。 在所有涉及电压和电势差的计算中,应该考虑数值计算的精度和取舍,避免由于精度问题导致的计算 错误。特别是在涉及到比较大小和判断条件的地方。 对于设备类之间的继承关系和方法重写,需要确保逻辑正确性和合理性,避免导致意外行为或不符合 预期的结果。 主函数输出部分: 在第一个 for 循环中遍历 series1.devices 时,可能会发生 ConcurrentModificationException 异常,因为在遍历过程中修改了集合中的元素。 在修改电阻的部分,可能存在逻辑错误。device.setResistance(parallel.BR()) 是将 M1 设备 的电阻值设置为并联电路的电阻,可能导致电路计算出现问题。 没有考虑 series1.devices 为空的情况,可能会导致空指针异常。 对于设备类型的判断部分,可能会出现逻辑错误,例如未考虑到某些特殊类型的设备。 在设置电压部分,可能会忽略了一些设备类型的处理,导致计算结果不准确。 在循环计算并联电路的子串联电路电压时,可能存在逻辑错误或计算顺序问题。
-
改进建议
首先是关于命名:建议按照 Java 命名规范,类名使用驼峰命名法,首字母大写;方法名、变量 用驼峰命名法,首字母小写。这样能让代码更易读。 控制设备类中的 adjust() 方法应当添加具体的功能实现,可以考虑在子类中重写该方法以实现不 同设备的具体调节操作。 建议在 GearSpeedController 和 ContinuousSpeedController 类中添加方法来设置和获取当 前档位或速率,方便外部使用。 在 ControlledDevice 类中的 calculateOutput() 方法中,应该使用 V1_V2 而不是 V1_V2, 以保持变量名一致性。 在 IncandescentLamp 和 FluorescentLamp 类中,建议将硬编码的数值提取成类的常量,增加 代码的可维护性。 在 FloorFan 类的 calculateOutput() 方法中的判断条件可能有误,应该根据实际调整需求进行 修正。 可以考虑增加注释来解释各个方法的作用,以提高代码的可读性和可维护性。 输出部分: 在第一个 for 循环中,可以考虑使用迭代器遍历 series1.devices,这样可以避免在遍历过程中 修改集合导致的 ConcurrentModificationException 异常。 Iterator<Device> iterator = series1.devices.iterator(); while(iterator.hasNext()){ Device device = iterator.next(); if(device.getName().equals("M1")){ series1.Mresistance(parallel.BR()); device.setResistance(parallel.BR()); } } 在判断设备类型并计算电压部分,可以考虑将不同类型设备的操作封装成方法,提高代码的可读性和 可维护性。 可以考虑在 series1.setV1_V2(V) 之后立即调用 series1.devicesV1_V2() 方法,确保及时计 算总电路中各个电器的电压值。 在循环计算并联电路的子串联电路的电压时,需要确保串联电路的顺序正确,以确保计算结果准确。 考虑添加注释来说明每段代码的作用,以提高代码的可读性和理解性。