家居强电电路模拟程序-3.4
家居强电电路模拟程序
家居强电电路模拟程序-3.4
这道题是一道模拟电路的题目,其中包含多种用电器(随着迭代次数的增加种类增多),第一次迭代有开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇。通过引脚进行连接,通过串联并联,使各个用电器进行工作。
基本电路形式如下图所示

我的设计思路
和上一次基本一样
用电器的设计
首先我先设计了一个Component类
class Component{
protected String name;
public Component(){}
public Component( String name) { this.name = name;}
public String getName() { return name; }
public void setName(String name) {this.name = name;}
}
之后我设计了VCC,GND,OPEN,fendang,lianxu,Blight,Rlight,Fan来表示用电器对Component进行继承(用共同属性为其子类)
这次添加:互斥开关
class huchi extends Component{
int huchi2=0;
int huchi3=0;
int huchi2cz=0;
int huchi3cz=0;
String zt;
int sc=0;
public void setV(double v) {this.v = v;}
public huchi(String name){super(name,5,0);}
public void r(int num){
if(num%2==0){r=5;huchi2=1;huchi3=0;}//偶数不变
else{r=10;huchi2=0;huchi3=1;}//奇数变
}
public void show(){
if(sc==0){zt="closed";}
else{zt="turned on";}
if(huchi3cz==1&&huchi2cz==1){zt="closed";}
System.out.println("@"+name+":"+zt);}
}
对于互斥开关,我踩了一些坑:
我以为一条电路只能有一个互斥开关,电阻可以随意切换,后来,我发现这样的话,测试点不合理,经过讨论,我发现一个互斥开关可以控制两个电路。
互斥开关可以两头接,这就添加了很多限制因素,我也是改正了很长时间。到最后还是有一些相关问题没改过来。
同时互斥开关的加入也添加了判断电路连接的很多限制因素,我又添加了几个判断电路是否连接的变量,这就有很多种情况,确实这种书写会让代码的可读性变低,后期我也会改成这个问题。
新增受控设备:受控窗帘
电路符号为“S”,代表受控窗帘。受控窗帘的最低工作电压为50伏特。当电压达到或超过这一阈值时,窗帘将开始正常工作。
窗帘的运作不受室外光照强度或室内空间大小的影响,但受室内灯光的光照强度控制。
我添加了一个计算电路总亮度的变量Light,这里设计的时候也出现了一些问题,比如受控窗帘,之后还存在发光的设备,这就无法将其计算上,所以我勉强最后计算了受控窗帘,这个办法实在是太笨了,
所以我得学学其他的方法,
然后我设计了一个电路类,这是做着道题目成功的关键,老师也给了设计建议:
1、电路设备类:描述所有电路设备的公共特征。
2、受控设备类、控制设备类:对应受控、控制设备
3、串联电路类:一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备
我也是按照老师的方法:将串联电路当做一个ArrayList
class Chuanlian{
List<Component>dianlu=new ArrayList<>();
}
class Binglian{
List<Chuanlian>dianlu=new ArrayList<>();
}
同时并联电路也是以串联电路为基础,创建的ArrayList,这样也方便的电路的链接。
对于输出:
我是用了比较笨的方法,建立一个 Allcontain类,其中包括储存各个Component的ArrayList,为了方便输出有正确的顺序,我添加了一个print()方法
public void print(){
sortCardsByNameNumber(openList);
for(Open open:openList){
open.show();
}
for(fendang fen:fendangList){
fen.show();
}
为了让同种用电器的按顺序输出
我搜索CSDN,使用了这样的方法
public static void sortCardsByNameNumber(List<Open> card) {
int n = card.size();
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) { // 注意这里修改了循环条件,以提高效率
int number1 = extractNumberFromName(card.get(j).getName());
int number2 = extractNumberFromName(card.get(j + 1).getName());
if (number1 > number2) { // 如果前一个数字大于后一个数字,则交换
Open temp = card.get(j);
card.set(j, card.get(j + 1));
card.set(j + 1, temp);
}
}
}
}
private static int extractNumberFromName(String name) {
Pattern pattern = Pattern.compile("K(\\d+)"); // 匹配以"F"开头后跟数字的字符串
Matcher matcher = pattern.matcher(name);
if (matcher.find()) {
return Integer.parseInt(matcher.group(1)); // 提取数字并转换为整数
}
throw new IllegalArgumentException("Name does not contain a valid number: " + name);
}
}
这个方法对于F3,F4,F1,F2...按顺序输出提供了极大地帮助
剩下的对输入信息的录入,我还是使用了正则表达式和split()函数
只是在设计排序的時候,会有些麻烦,后续我会进行一些改正,不然代码长度超过了长度。
这次做题我吸取了上次大作业的教训,做了很多注释,这让我长时间不看代码对代码的理解度大幅度提升,我每次都可以衔接上上次的思路,第一次大作业还是比较简单,第一次和第二次作业的衔接也很自然。
主要思路
首先,我为了判断开关对整个电路的影响,利用List进行各个开关的收集,奇数时候开关的状态是改变的,而偶数的时候开关的状态是闭合的,这样,在设计电路的时候,再个付一个连接状态的int,还有整条电路的电压,这样方便后续的分压计算。
然后,我还是用老方法对信息进行录入,同时将串并联都连接起来。
首先考虑开关的闭合情况,这个开关的判断我做了好久,判断每条电路是否有效,无效就不计算了,如果有效同时计算一下这个电路的总电阻。
HashMap<String,openpd> map = new HashMap<>();
//之后的操作:
if (matcher.find()) {
String name = matcher.group(1);
if (!map.containsKey(name)) { // 如果哈希表中没有这个名字,就新建一个openpd对象并添加到哈希表中
openpd opp = new openpd();
opp.name = name;
opp.num++;
map.put(name, opp);
} else { // 如果哈希表中已经有这个名字,就把对应的openpd对象取出来并更新num属性
openpd opp = map.get(name);
opp.num++;
}
可以看到我在判断开关这里使用了哈希表,为我提供了很大帮助!
然后我进行分档调速器和分压调速器的判断,因为只有一个,所以可以求出整个电路的电压。
然后根据并联的总电阻计算公式,并联总电阻的倒数等于各个并联支路电阻的倒数之和,这样就求出了并联电路的电阻。
对主路的录入:这道题只有一个并联分路,所以就考虑一个即可,别忘了和之前一样判断电路的开关,判断主路的链接。
主路链接了,就可以根据电路的总电阻进行分压了!按照电阻的比例,分压,并联的各个支路电压相同,最后就可以根据分得的电压值进行对用电器的判断啦!
最后按照题目要求输出结果!
总体来看这道题还是比较简单的,有了之前正确的思路,在向上面迭代就可以,前提是有一个完美正确的思路,这样之后的迭代才会更加顺利!
在做这道题时,出现了并联,与上道题有所不同,因为有串并联电路的链接,我添加了一个电路的抽象类,如下:
abstract class Dianlu{
private double v=0;
public double getV() {return v;}
public void setV(double v) {this.v = v;}
protected double r;
protected String name;
public abstract double getR();
public abstract void setR(double r);
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
为了后续的迭代和主路的链接,我也建立了以下:
ArrayList
Chuanlian zhulu = new Chuanlian();
2.缺点和不足:
对于这次大作业:
做作业的时候,还是遇到了很多问题,这次没有测试点,对我来说的确有些棘手了,最开始写完提交只有十几分(还是设计问题,考虑的不周到),让我感觉最麻烦的就是开关对电路的影响,没有开关时,有开关时,
开关有几个时,这使我修改了很多次,但这也使我的代码更加严谨了。
还有一个问题就是:当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类
型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。我也尝试了很多方法,最后正确了。
对于这次两次大作业,我觉得我应该将我的代码更加细分,我好多方法都直接写在了主函数里面,这使的我的代码造成了复用,占据了大量空间,篇幅过长,可读性差,还用在录入信息,和判断信息上,
我在使用正则表达式时存在了重复命名,在后续的大作业中,我会尽量改正我所存在的问题 。
这两次大作业的难度对来我说还是挺高的,毕竟期末考试临近,没什么时间写最后一题了,就没写出来,也是一个小遗憾吧,但也收获了不少。

浙公网安备 33010602011771号