家居强电电路模拟程序-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 allList = new ArrayList<>();
Chuanlian zhulu = new Chuanlian();
2.缺点和不足:

对于这次大作业:

做作业的时候,还是遇到了很多问题,这次没有测试点,对我来说的确有些棘手了,最开始写完提交只有十几分(还是设计问题,考虑的不周到),让我感觉最麻烦的就是开关对电路的影响,没有开关时,有开关时,

开关有几个时,这使我修改了很多次,但这也使我的代码更加严谨了。

还有一个问题就是:当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类

型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。我也尝试了很多方法,最后正确了。

对于这次两次大作业,我觉得我应该将我的代码更加细分,我好多方法都直接写在了主函数里面,这使的我的代码造成了复用,占据了大量空间,篇幅过长,可读性差,还用在录入信息,和判断信息上,

我在使用正则表达式时存在了重复命名,在后续的大作业中,我会尽量改正我所存在的问题 。

这两次大作业的难度对来我说还是挺高的,毕竟期末考试临近,没什么时间写最后一题了,就没写出来,也是一个小遗憾吧,但也收获了不少。

posted @ 2024-06-30 12:29  孙睿晗  阅读(106)  评论(0)    收藏  举报