一.前言:
在这几周,我们又进行了3次pta的题目训练。
首先是答题程序的最后一次迭代,答题程序-4,接着就是新的迭代,家居电路模拟程序。经过一段时间的学习,我对面向对象设计的理解进一步加深,这三次题集写起来也没有之前那么困难了,虽然还有不足,我仍在一次次答题中学到了很多。
以下是我的初步总结:
1.知识点
(1)首先是答题程序-4,经过前面的几次迭代,我已经对答题程序有了更深的理解,而答题程序-4仅仅只是在原有基础上加了一个继承关系,只需合理的运用继承,就能完成程序,但由于我之前的几次迭代并不完善,最后这道题还是没有拿下满分。
(2)接着是新的迭代,家居电路模拟程序。
实现电路模拟程序的关键是根据需求,创建对应的类与方法,并理清各个类之间的关系,从而实现电路的模拟。
相比答题判断程序,家居电路模拟的输入数据解析没有那么复杂了,答题程序中的数据解析与存储实在让人头疼,比如要报错,或者错了一点的不管,反正是各种要求,我要不断改变解析输入数据的代码来适应变化。而家居电路模拟并没有输入格式错误(至少现在没有),我对正则表达式的学习较浅,到现在还是采用substring等函数进行数据的解析与储存,这有着很大的弊端,一旦输入不按正常的来,我的代码就会出错,因此,学会正则表达式的运用,也是实现家居电路模拟的重要一步。
2.题量与难度
答题判断程序-4并没有增添多少东西,再完成选择填空题的继承关系后,我主要时间都花在对输入格式错误的检测上,完善之前的三次迭代,不过确实缺少样例,改不出来,最后还是差了几个测试点。
家居电路模拟-1逻辑简单,毕竟没有电阻,还只有串联一种连接方式,只要创建好了类与类中的方法,处理好类间联系,很快就可以实现,输入解析相交简单,电压也好计算。最后只要排好输出顺序,就可以完成程序。
家居电路模拟程序-2的难度直线上升,不仅加入了电阻,使电路电压的计算更加复杂,还新增了并联电路,使电路关系的处理难度大大上升。
同样的,数据的复杂度提升了,我之前有提过,正则表达式不太会,新的数据输入的解析花了我大量的时间(并存在很多漏洞,只不过样例中没检测出来),之后的迭代中,正则表达式的使用是必不可少的。为了计算电路,需要花费大量时间设计逻辑,并且还要处理计算误差。不过在足够的时间总算熬了过来,通过了所有测试点。
二.设计与分析
1.答题判断程序-4
其实大致设计已经在第一次Blog中差不多已经阐述完了,这里在分析一遍。
首先是正则表达式
Question 类:
这个类代表一个考试题目,包含题号、题目内容、标准答案等属性。
提供了一个构造方法来初始化这些属性。
matchingStandardAnswers 方法用于判断一个答案是否与标准答案匹配。
pQuestion 方法用于打印题目和标准答案。
(新增)TiankonandXuanzhe 类:
这个类继承自 Question 类,代表一种特定类型的题目---填空和选择题。
包含两个题目内容和两个答案选项。
提供了获取和设置这些属性的方法。
难点在于多选题的判断逻辑易于填空题相冲突。使用equals函数同时判断选择填空易造成混乱,这也是我的设计缺陷。
附图(由于图片体积过大,就不截整个类了):
Spaper 类:
这个类代表学生的试卷,包含学生答案、题目排名、试卷编号等属性。
提供了构造方法和获取、设置属性的方法。
Question_Paper 类:
这个类代表试卷中的一个问题,包含题目的顺序号、题目对象和题目分值。
judge_markAnswer 方法用于判断一个答案的得分。
TestPaper 类:
这个类代表一个完整的试卷,包含题目排名、分值和题目数量。
提供了构造方法和获取、设置属性的方法。
Answer 类:
这个类代表一个题目的答案,包含题目、答案内容、正确性和得分。
构造方法中会根据答案内容判断正确性和得分。
Stu 类:
这个类代表一个学生,包含学生的姓名和ID。
提供了构造方法和获取、设置属性的方法。
Pdscore 类:
这个类继承自 TestPaper 类,代表一个包含最终得分的试卷。
包含最终得分、分值数组和题目排名。
2.家居电路模拟程序-1
Device 抽象类:
这个类定义了所有设备共有的属性,如类型、ID、输入电压、输出电压和一个未在代码中使用的 dz 属性。
提供了获取和设置这些属性的通用方法。
包含三个构造方法,分别用于创建不同属性的设备对象。
定义了三个抽象方法:print、setStatus 和 OutputVoltage,这些方法需要在子类中实现。
kaiguan(开关)类:
这个类代表一个开关设备,包含一个表示开关状态的 boolean 属性。
print 方法返回开关的字符串表示。
setStatus 方法切换开关的状态。
OutputVoltage 方法根据开关的状态设置输出电压。
fengdan(分档调速器)类:
这个类代表一个可以调整速度的设备,包含一个 speed 属性。
setStatus 方法根据命令调整速度。
OutputVoltage 方法根据速度计算输出电压。
lianxv(连续调速器)类:
这个类代表一个具有连续速度调节的设备,包含一个 speed 属性。
setStatus 方法设置设备的速度。
OutputVoltage 方法根据速度设置输出电压。
baichi(白炽灯)类:
这个类代表一个白炽灯设备,根据输出电压计算光照强度。
print 方法返回光照强度的字符串表示。
OutputVoltage 方法设置输出电压。
riguang(日光灯)类:
这个类代表一个日光灯设备,根据输出电压提供固定的光照强度。
print 方法返回光照强度的字符串表示。
OutputVoltage 方法设置输出电压。
fan(风扇)类:
这个类代表一个风扇设备,根据输出电压计算转速。
print 方法返回转速的字符串表示。
OutputVoltage 方法设置输出电压。
大致设计
第一步:读取信息将,所有设备信息加入到sb(设备)中,把所有控制设备信息储存到commands中,方便后续操作
第二步:根据信息创建对应的类,并初步分类(控制设备,使用设备),改变控制设备状态(根据setStatus方法实现)
第三步:计算电路(程序一的计算非常简单,就不浪费篇幅展示了,程序2再细说),改变各个电器的状态并按照要求顺序输出
3.家居电路模拟程序-2
首先,添加新属性---电阻
此外,新增了3个类
ldfan(落地扇)类:
这个类代表一个落地扇设备,根据输出电压计算转速。
print 方法返回转速的字符串表示。
szOutputVoltage 方法设置输出电压。
getStatus 方法返回落地扇是否正在工作。
M 类:
这个类代表一个包含多个串联设备的模块,包含一个 linenum 属性、一个 ArrayList T 对象和 resistance 属性。
szOutputVoltage 方法设置输出电压。
getStatus 方法返回模块是否正在工作(断路)。
T 类:
这个类代表一个包含多个设备的串联电路,包含一个 id 属性、一个 isok 属性、一个 ArrayList Device对象和 resistance 属性。
Calculate 方法计算总电阻。
Check 方法检查是否该电路畅通。
更新了信息的读取
重点是电路的计算逻辑
设计如下:
将M,T类看作设备(不放入输出信息中)。
区分出主线路,看作一条串联电路。
计算T的电阻从而计算M的电阻,最后计算总电阻,再计算总电流。
对主路设备赋上总电流值,根据电阻计算电压从而更改状态。
M类计算出电压后,根据T类的电阻计算出每条路的电流,再给每条分路的设备计算电压更改状态。
其中有许多细节,比如每条分路的通路检测等等,都影响着电路计算。
附图:(检测路线开关)
输出逻辑大致不变
为了细分信息,我创建了多个hashmap使信息处理更方便。
三.踩坑心得
电阻计算误差:
1.电阻的计算涉及欧姆定律,即电压(V)等于电流(I)乘以电阻®。在计算过程中,需要确保电流和电压的值是准确的,并且电阻值也是正确的。
2.计算过程中可能存在浮点数运算的误差,比如电阻不小心设置成int类型(写太快了没注意)了,可以通过增加精度或者使用其他算法来减少误差。
题中遇见的还有就是1/r计算时造成的精度缺失(1/3和0.3333还是有区别的),这个错误很隐蔽,很难发现,再不断的测试中我才发现这个问题,之前再盲目的寻找其他错误,造成了大量时间的浪费。
信息的提取遇到困难:
在解析输入数据时,可能需要处理各种特殊情况,如数据格式规范、缺失数据等。
正则表达式的学习对于处理复杂的输入格式非常有用,但需要时间和实践来掌握。
可以尝试使用字符串处理函数(如substring、split等)来简化数据提取的过程,但需要注意这些函数的局限性,这让我花费了大量时间在数据的解析上。并使数据的储存冗余。
输出顺序逻辑的设计:
输出顺序需要根据电路的结构和计算结果来确定,可能需要多次尝试和调整才能得到正确的顺序。
尝试使用调试工具来检查电路的结构和计算结果,以便更好地理解输出顺序的逻辑。
考虑使用一些算法或规则来简化输出顺序的确定过程,例如按照电路的节点顺序输出,但是由于我的程序并没有储存接入,接出的信息,其实电路的连接信息与结构并不详细,只是根据linkedhashmap中的信息顺序进行连接顺序的判断,这是个很大的设计漏洞,不知道后续题集中是否会体现出来。
数据储存的冗余:
在存储电路数据时,可能存在一些冗余信息,如重复的电器名(没有区分接入接出),电阻值、重复的电压值等,
这使我的信息储存看起来十分混乱,造成了信息处理的一些不便。
可以尝试使用数据结构(如树、图等)来更有效地存储电路数据,减少冗余信息。
在存储数据时,可以考虑使用一些压缩算法或数据格式(如JSON、XML等)来减少存储空间。
总的来说,家居电路模拟程序的实现需要考虑多个方面,包括电阻计算误差、信息提取困难、输出顺序逻辑和数据储存冗余等。通过不断实践和学习,才可以逐步克服这些困难,提高程序的质量。
四.改进建议
答题判断程序-4
类的设计
Question 类中的 num、content 和 standardAnswer 应设置为私有,并通过 getter 和 setter 方法来访问和修改,以实现封装。
TiankonandXuanzhe、Spaper、TestPaper、Stu 和 Pdscore 类也应采用同样的封装原则。
构造函数
子类的构造函数如果没有显式调用父类的构造函数,Java 默认会调用父类的无参构造函数。如果父类没有无参构造函数,子类的构造函数必须显式调用父类的构造函数。
代码重复
toString() 方法在每个类中都有类似的实现,可以考虑抽取到一个基类中,以减少代码重复。
getter 和 setter 方法可以通过 Lombok 库来简化。
命名规范
类名、方法名和变量名应遵守 Java 的命名规范,如类名使用大驼峰命名法(TestPaper),变量和方法名使用小驼峰命名法(judgeMarkAnswer)。
成员变量可以使用更加描述性的名称,如 usepapernum 可以改为 usedPaperNumber。
代码逻辑
Answer 类中的 mark 和 score 可以考虑通过计算得到,而不需要在构造函数中显式设置。
Answer 类中的 score 可以通过调用 question.judge_markAnswer(answer) 来获取。
错误处理
代码中缺乏错误处理机制,例如,当传入的答案格式不正确时,应该有相应的处理逻辑。
代码可读性
添加必要的注释,说明每个类和方法的用途,有助于提高代码的可读性。
家居电路模拟程序-1
构造函数
子类的构造函数应该调用父类的相应构造函数来初始化共同属性。
方法实现
print 方法在每个子类中都有不同的实现,这是正确的,因为它依赖于每个设备的特性。
setStatus 和 OutputVoltage 方法也应该根据每个设备的特性来实现。
错误处理
代码中缺乏错误处理机制,例如,当传入的命令无效时,应该有相应的处理逻辑
代码可读性
添加必要的注释,说明每个类和方法的用途,有助于提高代码的可读性。
使用更具描述性的变量名和方法名,例如,将 setStatus 方法改为 changeStatus 可能更清晰。
代码逻辑
在 baichi 类的 print 方法中,lux 的计算逻辑可以简化,避免多个条件判断。
在 riguang 类的 print 方法中,可以使用三目运算符来简化 lux 的赋值逻辑。
家居电路模拟程序-2
代码结构和命名
代码中的类和函数命名应遵循Java的命名规范,使用驼峰式命名法。例如,将 kaiguan 改为 Kaiguan,fengdan 改为 Fengdan。
减少不必要的嵌套,使代码结构更清晰。例如,for (Map.Entry<String,String>entry: T.entrySet()) 这一行可以简化。
数据存储和访问
使用更合适的集合类型来存储数据,如 TreeMap 或 HashSet,以提高查找和排序的效率。
减少数据的冗余存储,例如,maindevicesname 和 maindevices 可以共享相同的数据。
考虑使用泛型来提高代码的通用性和可维护性。
错误处理和异常
添加适当的异常处理,以捕获和处理可能出现的异常情况,如数据格式错误、计算错误等。
使用更精确的数据类型,例如,浮点数运算应使用 double 类型,而不是 float。
性能优化
使用更高效的算法来计算电阻和电流,例如,使用数学库中的函数来处理浮点数运算。
优化循环结构,减少不必要的计算和比较。
五.总结
在前几周的PTA训练中,我完成了三次题目的迭代训练,包括答题程序的最后一次迭代和家居电路模拟程序的新迭代。这段时间的学习和实践使我对面向对象设计的理解更加深入,题目的编写也变得更加流畅。
在答题程序-4的开发过程中,我通过增加继承关系来扩展程序功能。虽然之前的基础并不完善,但我仍然在迭代中学习到了很多。在家居电路模拟程序的编写中,我学会了如何根据需求创建类和方法,以及如何处理类之间的关系。
在题目的编写过程中,我遇到了一些挑战。例如,数据解析和存储方面的问题,尤其是对正则表达式的使用不够熟练,导致我在数据解析上花费了大量的时间。此外,计算误差的处理、输出顺序的设计等方面也让我深刻认识到自己在编程中需要提高的地方。
在代码的质量方面,我意识到还有很多可以改进的地方。例如,类的设计可以更加完善,错误处理机制可以更加健全,代码的可读性也可以通过添加注释来提高。同时,我也认识到了自己在命名规范和代码逻辑方面需要更加严谨。
总的来说,这段时间的PTA训练让我在编程技能和设计思想方面都有了很大的提升。我将继续在实践中总结经验,学习新的设计理念和编程技能,以提高我的编程水平。
4986字