关于题目集7~8的总结
前言
第七次大作业和第八次大作业都是关于家居强电电路模拟程序的模拟和实现,题目综合性强信息多,每次迭代在前一次的基础上增加一到两个新的电路元件和增强电路的复杂性,需要综合考虑新的电路情况与前面的电路元件进行结合,电路的连接情况较为复杂,需要考虑多种特殊情况和某些电路元件来凝结的特殊性。这些在做项目需求分析时要考虑务必详细。这两次的题目集难度相比较大,主要在于不同的电路元件处理方式的差异和电路的各种异常如出现短路或断路对某些元件的特殊影响需要单独考虑。
第七次大作业
本次大作业新增了新的电路元件互斥开关和窗帘,且互斥开关为避免出现短路现象给不同的挡位设置了不同电阻,每个受控设备都具有各自的电阻,窗帘元件受到电路电压和电路光照强度的双重影响,因此在电路中存在窗帘时要单独考虑电路中是否有白炽灯或日光灯并求出总的光照强度。电路信息由一条连接信息占一行,用[]表示一组连接在一起的设备引脚给出,因此要用正则表达式读取给定的电路信息,互斥开关较为特殊,当互斥开关两端都给出时是以并联形式给出的,但实际上是串联电路,但也可以根据需要只取一边,不论是否连通,在设置带你路时要额外考虑。
设计分析
在设计电路将Device类作为所有设备类的父类,为方便同意处理,将串联类和并联类都看成是Device的一个子类,由于题目允许将一条串联电路视为一个设备给出,则在读到串联电路时将该串联电路中的所有设备组成list集合返回,由于互斥开关有三个引脚,既可以13引脚连接也可以23引脚连接,在默认情况下是13引脚两联,本次题目考虑多个并联电路串联在一起的情况,因此每个并联电路要有自己的处理方法,包括考虑短路和断路等异常情况。
相关源码解析:
if(str0.startsWith("H")){
String[] s = str0.split("-");
MuxSwitch muxSwitch = new MuxSwitch();
muxSwitch.name = s[0];
if(!MuxSwitchCount.containsKey(muxSwitch.name)){
//如果不存在就把value设置为1
if(!s[1].equals("1"))
MuxSwitchCount.put(muxSwitch.name,1);
}else{
//如果存在就value+1
if(!s[1].equals("1"))
MuxSwitchCount.put(muxSwitch.name,MuxSwitchCount.get(muxSwitch.name)+1);
}
boolean exit = false;
for(int i=0;i<devices.size();i++){
if(devices.get(i).name.equals(muxSwitch.name)){
exit = true;
break;
}
}
if (!exit) {
devices.add(muxSwitch);
if (s[1].equals("2")) {
muxSwitch.Pin = 2;
}else if(s[1].equals("3"))
muxSwitch.Pin = 3;
}
}
在读入互斥开关信息之前,创建了一个map转么用来储存互斥开关的名字和数量,如果互斥开关的数量为1说明该互斥开关使用了其中一边,如果当互斥开关的数量为2则说明该互斥开关的两边都要在电路中考虑,电路只会通过一边。
之所以互斥开关要这样处理是因为互斥开关给出的方式可能有变化,当给出一个map中某互斥开关的数量为2时,题目是以并联的形式给出的,但实际上互斥开关只有1引脚或2引脚才能与2引脚相接,电路也只会走一边,明显这其实是一个串联电路,互斥开挂断开的一段上的所有设备都不应包含在电路中,但是最后仍要输出,因此在最后再把电路中没有的元件即没有电流通过的设备加入主串联电路中。
而当互斥开关的数量为1时说明电路中只给出了互斥开关某一边的信息,而未给出的则不用考虑,但是再给出的一段并不一定是互斥开关连通的一端而有可能是断开的一段,那么相当于断路,但是当互斥开关是以并联形式给出时并不一定说明互斥开关再map中的数量为2,可能这就是一个并联电路但是两条支路上各有一个互斥开关,而各个互斥开关给出的是连通的信息还是不连通的信息要根据互斥开关引脚连接情况和互斥开关切换开关的情况,情况较为复杂,再互斥开关元件上要额外判断互斥开关的确切情况。注意:互斥开关是一个难点,要考虑的情况较复杂。普通开关是没有电阻的,而互斥开关无论哪条路都有电阻,但是互斥开关单独连在设备或某段电路上仍会导致短路现象,还有考虑串联支路上有多个互斥开关和普通开关串联导致该串联支路短路或断路的情况,因此互斥开关根据给出的情况不同处理的方式也有所不同。
for(int k=0;k< parallels.size();k++) {
Parallel parallel = parallels.get(k);
for (int i = 0; i < parallel.list.size(); i++) {
Contact contact = parallel.list.get(i);
for (int j = 0; j < contact.devices.size(); j++) {
Device device = contact.devices.get(j);
if(device instanceof MuxSwitch&&MuxSwitchCount.get(device.name)==2){
for(int n=0;n< contact.devices.size();n++)
contact.devices.get(n).direct=0;
break;
}else{
device.direct = 1;
}
}
}
}
这里将串联电路上的设备和并联电路上的设别加以区分,当设备是在串联电路上时direct设为0,当设备是在并联电路上时direct设为1,但由于互斥开关在map中的值为2时是以并联方式给出的但是实际上这是一条串联电路,因此将与该互斥开关相连的所有设备的direct全部设置为0.
public void ParallelJudgement() {
for(int i=0;i<list.size();i++){
Contact contact = list.get(i);
int count=0;
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
if(device instanceof Switcher&&((Switcher)device).flag==1)
count++;
if(device instanceof MuxSwitch&&((MuxSwitch)device).isUseful()%10!=0) {
count++;
}
}
if(count==contact.devices.size()){
//这条路短路
this.isShort = true;
contact.flag = true;
for(int j=0;j< list.size();j++){
Contact contact1 = list.get(j);
if(!contact1.flag){
for(int k=0;k<contact1.devices.size();k++)
contact1.devices.get(k).useful = false;
}
}
}
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
if(device instanceof Switcher&&((Switcher)device).flag==0){
for(int k=0;k<contact.devices.size();k++){
contact.devices.get(k).useful = false;
}
}
if(device instanceof MuxSwitch&&((MuxSwitch)device).isUseful()%10==0){
for(int k=0;k<contact.devices.size();k++){
contact.devices.get(k).useful = false;
}
}
}
}
}
当读到并联电路时调用该方法处理,主要目的是判断该并联是否短路和断路,当出现短路情况时将被短路的所有串联支路上的所有设备的useful属性改为false,意思是该设备实际上没有电流通过,或者当出现断路现象时,将该断路支路上的所有设备的useful属性改为false。如果并联电路中所有支路全部断开,则该并联电路无效,直接将总电压变0.
//计算电路总电阻
double TotalResist = 0;
for (int i = 0; i < contacts.get(contacts.size() - 1).devices.size(); i++) {
Device device = contacts.get(contacts.size() - 1).devices.get(i);
if (device.getTypeValue() <= 10)
TotalResist += device.getResist();
else if (device.getTypeValue() == 100) {
Parallel parallel = (Parallel) device;
//没出现短路
if(!parallel.isShort){
int count=0,useful=0;
for(int j=0;j<parallel.list.size();j++){
Contact contact = parallel.list.get(j);
for(int k=0;k<contact.devices.size();k++){
Device device1 = contact.devices.get(k);
if(device1 instanceof MuxSwitch){
count++;
if(((MuxSwitch) device1).isUseful()==21||((MuxSwitch) device1).isUseful()==31)
useful++;
break;
}
}
}
if(useful==1)
TotalResist+= parallel.getSwitchResist();
else
TotalResist+= parallel.getResist();
}else{
//这条并联短路
for(int j=0;j<parallel.list.size();j++){
Contact contact = parallel.list.get(j);
if(contact.flag){
for(int k=0;k<contact.devices.size();k++)
TotalResist+=contact.devices.get(k).getResist();
}
}
}
} else if (device.getTypeValue() == 50) {
for (int j = 0; j < contacts.size(); j++) {
if (contacts.get(j).name.equals(device.getName())) {
List<Device> list2 = contacts.get(j).devices;
for (int k = 0; k < list2.size(); k++) {
TotalResist += list2.get(k).getResist();
}
}
}
}
}
这里计算电路的总电阻,当遇到并联电路时先判断是否短路,如果出现短路从并联的所有支路中找到有效的支路遍历所有设备求电阻,在如果并联正常,就用物理方式求解电路的总电阻,之后开始给每个有效的设备分压,当遇到串联的设备,直接用比例赋电压,如果是并联,就调用并联的求电压方法,为并联的每个设备分压,并联分压方法代码如下:
if (device.direct==1 ) {
Parallel parallel = null;
for(int j=0;j<parallels.size();j++){
Parallel parallel1 = parallels.get(j);
for(int k=0;k<parallel1.list.size();k++){
Contact contact = parallel1.list.get(k);
for(int n = 0;n<contact.devices.size();n++){
Device device1 = contact.devices.get(n);
if(device1.getName().equals(device.getName())){
parallel = parallel1;
}
}
}
}
double parallelValue = (parallel.getResist()/TotalResist)*Function.value; //整个并联电路的分压
device.value = parallel.getRate(device)*parallelValue;
}
最后将电路总串联上没有的设备加入,最后调用每个设备的打印方法输出。
相关类图
踩坑分析
这里易错的地方有以下几点:
1.对互斥开关的理解,互斥开关虽然是以并联方式给出且有三个引脚,但是只有两个引脚相连因此看成是一条串联电路,这里对该互斥开关哪条支路连进电路中要判断准确,其次,互斥开关初始状态是引脚1和引脚3相连,但是通过切换开关状态的方式使引脚2与引脚3相连,要根据两方面综合考虑。
2.互斥开关也可能是以串联方式给出,可以是一个互斥开关以串联方式出现,也可以是多个互斥开关以并联方式出现,两种情况处理起来不相同,要区分开来处理
3.窗帘处理的时候既要考虑电压也要考虑光照,由于只考虑电路中设备的光照,因此在窗帘的输入方法中要统计电路中的光照强度大小
这里最重要也是最难的就是互斥开关的处理,由于互斥开关变化多样,我一开始没有想到互斥开关可以以串联形式单连接一边,以为互斥开关只能以并联形式出现导致电路设计不全面最后不得不将代码全部重新设计。这里也提醒了在做需求分析时务必要做到全面,严谨。
改进建议
在计算电路电阻时考虑不周,将有互斥开关的并联电路和没有互斥开关的电联电路的电阻分来来用两个方法计算,这样实际上对互斥开关真实并联的情况的电阻没有考虑,计算逻辑也很麻烦,应该将两个方法合一或者将没有互斥开关的电路在前面就处理,后面处理起来就简便。
第八次大作业
前言
第八次大作业是在第七次作业的基础上进一步提高要求,要求在输入每个设备的信息后输出每个设备两个引脚的电压,并且考虑电流过大问题,每个设备都设定了一个最大电流,当经过设备电流超过最大电流时,输出 exceeding current limit error。本次题目考虑在并联电路的串联电路中存在并联电路,存在嵌套关系。且新增元件二极管,当正方向放入电路中电阻为0,当反方向放入电路中时电阻无穷大
设计分析
public void ParallelJudgement() {
for(int i=0;i<list.size();i++){
Contact contact = list.get(i);
int count=0;
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
if(device instanceof Parallel){
((Parallel) device).ParallelJudgement();
if(((Parallel) device).isUseful()==false){
for(int n=0;n<contact.devices.size();n++)
contact.devices.get(n).useful = false;
}
}
if(device instanceof Switcher&&((Switcher)device).flag==1)
count++;
if(device instanceof MuxSwitch&&((MuxSwitch)device).isUseful()%10!=0) {
count++;
}
if(device instanceof Parallel&&((Parallel)device).isShort)
count++;
}
if(count==contact.devices.size()){
//这条路短路
this.isShort = true;
contact.flag = true;
for(int j=0;j< list.size();j++){
Contact contact1 = list.get(j);
if(!contact1.flag){
for(int k=0;k<contact1.devices.size();k++)
contact1.devices.get(k).useful = false;
}
}
}
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
if(device instanceof Switcher&&((Switcher)device).flag==0){
for(int k=0;k<contact.devices.size();k++){
contact.devices.get(k).useful = false;
}
}
if(device instanceof MuxSwitch&&((MuxSwitch)device).isUseful()%10==0){
for(int k=0;k<contact.devices.size();k++){
contact.devices.get(k).useful = false;
}
}
if(device instanceof Diode&& !((Diode) device).direction){
for(int k=0;k<contact.devices.size();k++){
contact.devices.get(k).useful = false;
}
}
}
}
}
当遇到二极管且方向为正时相当于导线,在考虑短路情况时要考虑,当方向为反时,该支路断路,该支路上所有设备全部设为无效,其他部分与上次大作业基本上相同。
public void setCircuit(double paraValue){ //给并联分流
for(int i=0;i<list.size();i++){
Contact contact = list.get(i);
double total = 0;
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
total+=device.getResist();
}
for(int j=0;j<contact.devices.size();j++){
Device device = contact.devices.get(j);
if(device.useful) {
if (device instanceof Parallel) {
Parallel parallel = (Parallel) device;
parallel.setCircuit(device.value);
} else {
if(total!=0)
device.Electricity = paraValue / total;
}
}
}
}
}
这里是给并联电路的每个设备分配电流,由于可能存在串联支路上有并联电路的情况,因此计算电流要一直计算到最里层的串联支路的电流,因为外层的电流等于里层支路电流之和,要确保每个设备都准确分配了各自的电流。
for (int i = 0; i < contacts.get(contacts.size() - 1).devices.size(); i++){
Device device = contacts.get(contacts.size() - 1).devices.get(i);
if(device.getTypeValue()<20){ //普通设备
device.pin1Value = v;
v-=device.value;
device.pin2Value = v;
}
else if(device.getTypeValue()==100){ //并联
Parallel parallel = (Parallel)device;
double[] values = new double[parallel.list.size()];
for(int j=0;j<parallel.list.size();j++){
values[j] = Function.v;
}
for(int j=0;j<parallel.list.size();j++){
Contact contact = parallel.list.get(j);
if(!contact.hasParallel()){ //正常的串联支路
for(int k=0;k<contact.devices.size();k++){
Device device1 = contact.devices.get(k);
device1.pin1Value = values[j];
values[j]-=device1.value;
device1.pin2Value = values[j];
}
}else{ //并联的串联支路中存在并联
for(int k=0;k<contact.devices.size();k++){
Device device1 = contact.devices.get(k);
if(device1.getTypeValue()<20){
device1.pin1Value = values[j];
values[j]-=device1.value;
if(contact.devices.get(k+1)!=null&&contact.devices.get(k+1).useful)
device1.pin2Value = values[j];
}else if(device1.getTypeValue()==100){ //遇到并联电路
Parallel parallel1 = (Parallel)device1;
parallel1.setPinValue();
}
}
}
}
}
}
这里给设备两个引脚赋电压值,从总电压开始,每次遇到设备分压都用总电压减去设备分压值,遇到并联电路时则每条串联支路的电压都相同,急促依次为每个引脚赋电压值,这里要注意互斥开关,要考虑清楚互斥开关是那两个开关接通,一定有一个引脚的电压为0.
踩坑心得
做需求分析和实现代码时要注意以下几点:
1.电路中存在互斥开关,二极管等特殊元件,可能会导致电路出现断路和短路的情况出现,在判断电路的异常情况时要多注意这些元件
2.计算电流时要考虑串联中嵌套并联的情况,一开始在设计的时候为每个设备分压,以为设备的电流就直接用电压除设别的电阻,实际上这种想法是错误的,比如开关,不分压且没有电阻,无法通过这种方式计算通过开关的电流,如果存在嵌套并联的情况,那么串联的电流等于嵌套并联的总电流
3.在为设别两端分压时要注意,当电流经过某设备时在后面断开了,那么该设备前面的引脚有电压而后面的引脚电压为0,不能仅仅考虑设备分压的情况,还要综合考虑各种其他的情况
改进意见
在计算电流的方法上存在问题,如果在一条串联电路上有嵌套并联且有多个的情况下,最好能递归处理,完全靠逻辑去处理太复杂而且情况考虑不全面,在计算设备两端引脚的分压时也有错误,如果设别前面或者后面断开时设备的引脚电压是不相同的
两次作业的大总结
1.这类题目经过多次迭代难度大大增强尤其是最后一次,电路设计都十分苦难,有各种特殊情况不知道怎么去考虑,在前面的题目出现问题没有解决那么后面问题一尺存在且不一定能被发现
2.提示点太笼统不知道什么情况才是测试点,有时候改对了很多测试用例但是都不是题目要求的测试点,题目给的测试点不具有代表性
3.大作业一直只是做,如果有没有思路的很难动笔,别人的也很难看懂,导致这次以及以后的迭代都很难产生思路,我认为老师要适当的讲解和提示。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~