7~8次作业总结

news/2024/12/28 23:25:28/文章来源:https://www.cnblogs.com/ling195/p/18638007

一、前言

  1. 家居强电电路模拟程序-3
  • 知识点:所考察的知识点与前两次任务相比区别不大,都是主要用到封装,继承和多态等面向对象的基础操作,所用类的结构也没有多大变化,主要是新增了互斥开关以及电路中可能存在多条并联电路,这要求我对电路的相应知识有更多的了解。
  • 题量分析:需要识别控制命令和电路的关系,将两者分开识别解析,能够正确的处理电路中的包含关系。
  • 难度分析:本题的主要难点有两个,一是新加入的互斥开关,二是串联电路中包含了多条串联电路。互斥开关作为一种特殊的电路元件,具有三个引脚,这意味着它的状态有两种,且电阻变化多达四种,其复杂性在于引脚可以连接在不同的电路上,这大大增加了状态判断和电阻计算的难度。为了应对这个问题,我考虑将互斥开关拆分为两个独立的组件进行计算和判断,虽然这种方法增加了计算的复杂性,但能够确保每个引脚的状态都被准确模拟。另一方面,多条串联电路的存在也很难解决,在我之前的代码设计中,如果一条串联电路包含其他电路,很容易干扰到输入源的识别,从而影响到各个设备的输出电压的正确计算。
  1. 家居强电电路模拟程序-4
    这一次出现了另一个麻烦的元器件,题目要求增加二极管元件,其电路特性为:正向导通,反向截止。在处理二极管时,需要仔细考虑其正向和反向的电流流向,以及它在不同电压下的导通和截止状态,这对电路模拟算法提出了更高的要求。同时,题目还要求在并联电路中再包含并联电路,这无疑增加了电路的复杂性和层次性。在之前的并联电路处理中,我已经需要关注各个并联分支的电流分配和电压相等性,而现在,当并联电路内部再嵌套并联电路时,我们不仅要考虑外部并联分支的电流和电压,还需要深入到内部并联电路中,对每个分支进行细致的分析和计算。这要求处理部分的算法不仅要具备处理复杂电路结构的能力,还要能够准确模拟和计算各个电路元件之间的相互作用和影响。说实话,这一次的难度确实太大了,由于第七次作业的问题都没有很好的解决,导致这一次更加做不出来,我初步考虑二极管可以在引脚上下手,但实际还未处理成功。

二、设计与分析

  1. 家居强电电路模拟程序-3
    UML类图

    Device 是一个抽象类,它定义了所有设备的基本属性和方法。例如,identifier、pin1 和 pin2 属性,以及 getOutput 方法。
    ControlledDevice 也是一个抽象类,继承自 Device,增加了 toggle 方法。
    Fan、Curtain、LFan、IncandescentLight 和 FluorescentLight 都是具体的设备类,它们都继承自 ControlledDevice。这些类实现了 getOutput 方法,并且每个类都有自己的构造函数。
    SeriesCircuit 和 ParallelCircuit 分别表示串联电路和并联电路。它们都继承自 Device,并且包含了一个 devices 属性,用于存储电路中的设备。
    这些电路类也实现了 getOutput 方法,用于计算电路的输出电压。
    DeviceController 是一个控制器类,它管理多个设备和电路。它包含了 seriesCircuits 和 parallelCircuits 属性,分别用于存储串联电路和并联电路。它还包含了一些方法,如 addDevice、removeDevice 等,用于管理和操作设备。
    各类关系:包括继承关系、关联关系和依赖关系。例如,DeviceController 与 SeriesCircuit 和 ParallelCircuit 之间是关联关系,而 SeriesCircuit 和 ParallelCircuit 与 Device 之间是聚合关系。
    生成报表:

    通过图表可以看出:最复杂的方法在第 349 行,为Curtain.addDevice(),最大复杂度为 92。
    Line Number of Deepest Block: 最深的代码块在第 493 行
    Maximum Block Depth: 最大代码块深度为 9+
    Average Block Depth: 平均代码块深度为 4.44
    Average Complexity: 平均复杂度为 5.03
    这个文件包含了大量的代码,并且有较高的分支语句比例。文件中有较多的注释(21.2%),这有助于代码的可读性和维护性。平均每个类有 6.60 个方法,平均每个方法有 7.30 条语句,说明代码结构较为合理。最复杂的方法是 Curtain.addDevice(),其复杂度为 92,位于第 349 行。代码块的最大深度为 9+,平均深度为 4.44,表明代码有一定的嵌套层次。

  2. 家居强电电路模拟程序-4
    UML类图

    在此前的基础上加入了二极管类

分支语句占总语句的25.8%,这表明代码中有较多的条件判断逻辑。从图中可以看出,深度为3和4的代码块最多,分别有约80和60条语句。这表明代码的主要部分集中在中等深度的代码块中,整体结构较为清晰。注释比例较高,方法数量适中,复杂度在合理范围内。
三、踩坑心得及改进

  1. 第七次作业
  • 在之前的代码中,我判断主电路的逻辑是找到最后一个串联电路,没有考虑顺序问题
 int seriesNumber = Integer.parseInt(identifier.substring(1)); // 提取编号数字lastSeriesCircuitNumber = Math.max(lastSeriesCircuitNumber, seriesNumber);

在这里找到lastSeriesCircuitNumber,是最后一条串联电路(而我判断最后一条电路的逻辑是找到编号最大的串联电路),然后在finalizeLastSeriesCircuit()添加主电路的方法中,将编号为lastSeriesCircuitNumber的串联电路加在主电路中,这在前两次的代码中没有问题,因为不涉及到乱序问题,而这一次有一些样例,例如:

可以看到在这个样例中,T3是主电路,但是在这之前还有T4、T5电路,导致主电路判断错误。
经过以下修改:

if (line.contains("VCC")) {//mainCircuit = newCircuit; // 更新主电路为当前序列电路lastSeriesCircuitNumber = seriesNumber;}

判断以VCC开头的电路是主电路,解决这个问题。

  • 互斥开关存在与两个电路中,这两个电路创建时都会创建一个新的互斥开关设备,导致最后计算电压时没有使用正确的设备,为解决这个问题,引入了一个映射来存放所有已经创建过的设备
    private Map<String, Device> createdDevices = new HashMap<>(); // 存储已创建的设备
    在 createDevice 方法中改进 MutualSwitch 设备的创建逻辑:
else if (deviceId.startsWith("H")) {device = createdDevices.get(deviceId); // 尝试从已创建设备中获取if (device == null) {device = new MutualSwitch(deviceId, pin, ""); // 创建互斥开关createdDevices.put(deviceId, device); // 存储已创建的互斥开关}
}

通过这些改进,确保了同一个MutualSwitch设备在不同的串联电路中引用的是同一个实例,从而避免了重复创建和错误的结果。

*串联电路中的包含

for (String pin : connectionArray) {// 确保引脚格式正确if (!pin.startsWith("K") && !pin.startsWith("F") &&!pin.startsWith("L") && !pin.startsWith("D") &&!pin.startsWith("B") && !pin.startsWith("R") && !pin.startsWith("M") && !pin.startsWith("A") && !pin.startsWith("H")&& !pin.startsWith("S")&& !pin.startsWith("T")) {continue; // 跳过非设备引脚}

我尝试在这里加入串联电路的标识,试图让其作为一个设备被添加到列表中去,但仅仅这样,添加到设备的串联电路是一个空的,不包含任何设备。这个问题我没有解决,没想到办法让这些电路正确包含

  • 关于互斥开关
    一开始,我设置开关电阻的逻辑仅仅是这样:
public double getR() {if(isBranch1Active == true) {R = resistanceBetween1And2;}return R;

这就导致我在后面调用它时,电阻只会返回5或无穷大。
后来我意识到,互斥开关的电阻应该有四种情况,我没有办法在一个getR中包含所有的情况。通过询问同学的方法,我了解到可以将这个互斥开关拆成两个,将它们分开来判断,但这需要在后期计算时添加很多判断条件。并且我尝试了这个方法后,还是没有解决该问题。
2. 第八次作业

  • 判断短路,若短路输出警告
    int flag = deviceController.calculateInputV();
    添加一个标志位
if(SertotalR == 0)return 1;else {outputV = device.getInputSources().getOutputV();//System.out.println("short circuit error");return 1;}

calculateInputV()的返回值如果为1,说明短路,在最后输出short circuit error

这量次实验中遇到的问题及解决总结如下:

  • 原先通过找到编号最大的串联电路作为主电路,但在某些情况下,如主电路编号并非最大时,会引发错误。
    解决方案:调整为根据电路是否以“VCC”开头来确定主电路,因为“VCC”代表电源正极,是电路的主要输入点。这一改动确保了主电路的正确识别。
  • 引入了一个HashMap来存放所有已经创建过的设备。在创建设备时,首先尝试从映射中获取已创建的设备实例,如果不存在则创建新的实例并添加到映射中。这一改动确保了同一个互斥开关设备在不同的串联电路中引用的是同一个实例。
  • 在计算电压时,需要确保正确地处理电路中的各个设备和它们之间的连接关系。但原先的电压计算逻辑存在漏洞,导致在某些情况下电压值计算错误。

四、总结
在完成家居强电电路模拟程序-3和-4的过程中,我对代码结构的设计以及各个极端情况的考虑有了更深入的理解。这两次作业不仅要求我深入理解电路的基本原理,还挑战了我在代码设计和优化方面的能力。

在第三次作业中,我遇到了多个挑战。首先,互斥开关的引入大大增加了电路模拟的复杂性。互斥开关具有三个引脚和四种可能的电阻状态,且其引脚可以连接在不同的电路上,这使得状态判断和电阻计算变得异常困难。为了应对这个问题,我采用了将互斥开关拆分为两个独立组件的方法进行计算和判断,虽然这种方法增加了计算的复杂性,但确保了每个引脚的状态都能被准确模拟。此外,我还发现原先的通过找到编号最大的串联电路作为主电路的方法在某些情况下会出错,因此我调整为根据电路是否以“VCC”开头来确定主电路,这一改动确保了主电路的正确识别。同时,为了处理同一个互斥开关设备在不同串联电路中引用的问题,我引入了一个HashMap来存放所有已经创建过的设备,确保了设备实例的唯一性。

在第四次作业中,二极管的加入进一步提升了电路的复杂性。二极管具有正向导通、反向截止的特性,为了准确模拟二极管的行为,我在代码中增加了对二极管特性的判断和处理逻辑。同时,题目还要求处理包含多层并联电路的复杂结构,这要求我在处理并联电路时不仅要考虑外部并联分支的电流和电压,还需要深入到内部并联电路中,对每个分支进行细致的分析和计算。这一要求大大增加了代码的复杂性和运行时间,但通过不断地调试和优化,我最终成功地实现了对多层并联电路的正确模拟。

在完成这两次作业的过程中,我也深刻体会到了代码可读性和可维护性的重要性。之前几次还不明显,但随着代码量的增加,很容易出现过一段时间就忘记了之前写过的东西,给代码适当的注释必不可少。并且我与一些同学交谈过,听见他们说第七次的代码其实改动的不多,这便是他们代码设计的优越。在我的代码中,每一次添加设备,尤其是涉及到电路的相互包含,总是会出现不少问题,我的设计并没有很好的处理电路之间的联系,这两次作业写的极其艰难。

五、学期总结
这一个学期的作业已经结束,在这八次的迭代中我确实收获了很多。说实在的,我此前从没写过难度这么大的题,基本每一次的题目我都需要很长的时间来慢慢修改。当然,做了这些效果也是显著的,我对java了解增长的飞快,通过切身体会,更加理解了面向对象语言和面向程序语言的不同。在这么多题目的洗礼下,我已经从第一次刚见到题的无从下手到现在学会先规划类图,来理清楚需要的类的关系,虽然我现在对这些设计还不是特别熟悉,设计的也不太好,容易出现每一次迭代都需要在上一次的基础上大概的情况,但总体来说,我还是在这方面有了一些心得。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站被挂马,如何处理?

网站被挂马后,您希望能够尽快清理并防止再次发生。这类问题可能由以下几个原因引起:木马文件植入: 黑客可能通过漏洞植入了木马文件,导致网站被挂马。建议您立即删除所有可疑文件,并进行全面扫描。可以使用专业的杀毒软件或在线扫描工具(如Sucuri SiteCheck)检查网站文件…

无法安装网站模板

FTP权限问题: FTP账户可能没有足够的权限上传和解压模板文件。建议您检查FTP账户的权限设置,确保具有读写权限。可以通过FTP客户端或服务器管理工具检查和修改FTP账户权限。如果权限不足,可以联系服务器提供商申请提升权限。模板文件损坏或不完整: 模板文件可能在下载或上传…

数据库备份和导入失败

在后台使用数据库自带的备份功能时,选择备份到指定位置失败,提示操作失败:500。这类问题可能由以下几个原因引起:InnoDB引擎限制: InnoDB引擎无法直接复制源文件进行备份和恢复。建议您使用SQL方式导出SQL备份文件。具体步骤如下:登录数据库管理工具(如phpMyAdmin) 选择…

127.0.0.1服务器无法访问网页

Web服务器未启动或异常: Web服务器(如Nginx或Apache)可能未启动或出现异常。可以通过命令systemctl status nginx(适用于Nginx)或systemctl status httpd(适用于Apache)检查Web服务器的状态。如果服务未启动或已停止,可以尝试重启Web服务器:systemctl restart nginx或…

网站手机访问报错“The table common_visit is full”的解决方法

您好,关于您提到的网站手机访问时出现错误“The table common_visit is full”,我们非常理解您的困扰。这个错误通常是由于用户访问日志表(common_visit)空间不足引起的。为了帮助您解决这个问题,以下是详细的分析和解决方案:原因分析:日志表容量限制:当用户访问量较大…

服务器CPU和内存升级时如何避免数据丢失?

您好,关于您提到的服务器CPU和内存升级过程中如何避免数据丢失的问题,我们非常理解您的担忧。为了确保升级过程中的数据安全,以下是一些建议和步骤供您参考:提前备份数据:在进行任何硬件升级之前,强烈建议您先对现有数据进行全面备份。这不仅包括数据库、网站文件等关键数…

如何在云服务器上开放特定端口?

您好,如果您需要在CentOS服务器上开放特定端口(如843、3000、3001、19923、80等),可以通过配置防火墙规则来实现。以下是详细的步骤和注意事项,帮助您顺利完成端口开放操作。 首先,确保您的服务器已经安装了iptables或firewalld作为防火墙管理工具。对于CentOS 7及以上版…

网站站点图片丢失 - 云服务器问题

问题: 为什么网站站点的图片突然丢失?我已经尝试恢复备份,但问题依然存在。请提供详细的排查步骤和解决方案。 答案: 您好,网站站点图片丢失可能是由多种原因引起的。以下是详细的排查步骤和解决方案:确认图片存储位置: 确认图片存储的位置是否正确。某些情况下,图片可…

升级至 2016 系统后无法登录 - 云服务器问题

问题: 为什么升级至 Windows Server 2016 系统后无法登录?我已经尝试重启服务器,但问题依然存在。请提供详细的排查步骤和解决方案。 答案: 您好,升级至 Windows Server 2016 系统后无法登录可能是由多种原因引起的。以下是详细的排查步骤和解决方案:确认远程桌面服务状态…

说明与笔记导航(1228CMT基本完工)

更新进度:CMT除二维平面应力,其余均有初版笔记。为什么写这么多B东西? 其一呢是帮助我自己,边写笔记边梳理知识;其二呢是帮助各位义父义母考试成功。 更新进度与内容说明 12.27:突击复习CMT,其中中心差分和迎风差分已更新,交错网格、SIMPLE和SIMPLEC的很快跟进。 目前进…