OOP课第二阶段总结

oop · 浏览次数 : 0

小编点评

**设计能力不足的分析和解决方法:** 1. **使用布尔变量表示开关状态:** - 虽然使用 int 类型数据来表示开关状态,但没有考虑其优缺点或性能影响。 - 可以考虑使用布尔变量更清晰地表示开关状态,并进行优化。 2. **并联电路连通性判定:** - 现有的方法只考虑串联电路连通度,而并联电路的连通性需要考虑。 - 可以引入并联电路中所有串联电路的连通度判断,并根据其结果调整开关状态。 3. **测试点设计:** - 题目中没有明确的测试点提示,导致设计难度增加。 - 建议在测试点中明确定义变量的范围、初始值和计算方式,以确保测试结果的准确性。 **优化建议:** 1. **使用布尔变量存储开关状态:** - 创建一个布尔变量,将其设置为开关状态的初始值。 - 在每遇到开关输入信息时,修改布尔变量值。 - 最后判断开关状态时,使用布尔变量,提高效率。 2. **深入理解并联电路连通性:** - 研究并联电路的连接规则和理论知识。 - 考虑各种情况下并联电路的连通性和断开状态。 3. **明确测试点设计思路:** - 明确测试点的功能、范围和要求。 - 在测试点中使用变量、条件和逻辑运算。 4. **利用测试结果进行代码优化:** - 根据测试结果,优化代码逻辑和性能。 - 考虑使用布尔变量、缓存和其他优化技术。

正文

OOP课第二阶段总结

  • 前言

    • 作为第二次3+1的总结,明显感受到了此次题目集越来越复杂,结合了实际的物理知识来解决现实中的电路问题。因为电路可以一直扩展下去,情况千变万化,难以像上次题目集一样找到一个呆板的做法。这次题目集,让很多人连题目都无法理解,代码也是无从下手,因为这些人根本不知道如何去设计,如何去完成电路上的整个过程,也就是没有抓到本质。

    • 目前题目集只迭代了两次,从最开始的单一串联电路、单一设备,到现在的由多个串联电路组成的并联电路、多个设备,这两次迭代已经可以看出这次题目集的复杂性。再经历两次迭代后,将完整的模拟电路中可能出现的所有情况(多并联、多串联、短路、双向开关......),所以对我们前期的设计思路要求缜密且严谨。

    • 而且在第二次迭代中,题目采取了不提示测试点的手段,让很多学生举步维艰,测试了N个由自己或同学创造的样例后仍然找不到错误,最终停留在了88、91、94分。由于学生代码设计上的缺陷以及题目不提示测试点的手段,使得很多人痛不欲生,”明明别人的样例我都过了,可为什么他拿到了100而我只有94呢?“,在这样的自我怀疑中不断地寻找错误。运气好的同学也许再测试了一些样例后可以找到错误,可运气不好的同学可能等到题目结束的最后一刻都没有找到一丁点错误,可是事实就是他错了,但是错得看起来天衣无缝,无法叫人发现。

    • 并且我统计了前六次题目集得提交以及通过情况:

      由此不难看出,题目集的实际通过率(通过人数/考试人数)处于0.2~0.5这个区间,其中最难的一次为题目集三,实际通过率仅为0.178,但提交数量却是最多的,三百人提交了将近一万三千份答卷。学生在经历了这么多次练习后,通过率的总体趋势却是起起伏伏,当然这也和题目难度相关。题目集一和五都是作为两次大迭代的开端,故而各个数据都非常相似,由此我们也许可以预测一下,下一次题目集的通过率可能会达到第二次迭代最低。

  • 正文

    • 第四次题目集

      从上表可以看出,在经历了第三次题目集的大洗劫后,居然得到了很大的改善,不仅提交量减少了,而且提交通过率还提高了不少。也许是因为同学在第三次题目集下了很大的功夫还吃了亏,将代码的质量提高了不少。但这并不是今天的重点。

      UML类图:

    • 第五次题目集

      1. 题目:

        这次题目集便是第二次大迭代的开端,主要内容为计算单一串联电路上的设备状态

        题目主干:

        设计一个智能家居强电电路模拟系统:

        模拟的控制设备包括:开关、分档调速器、连续调速器。

        模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。

        并且提供了四次迭代的区别:

        迭代1:只有一条线路,所有元件串联
        迭代2:线路中包含一个并联电路
        迭代3:线路中包含多个串联起来的并联电路
        迭代4:并联电路之间可能出现包含关系

        这就很考验学生的总体设计能力,不能只顾眼前的题目集,还要考虑到为题目集的迭代做好准备。

      2. 设计思路:

        • 因为这次题目的设备并没有电阻,所以无法使用正常的根据电阻求分压的方法来计算设备状态,也因此,电路中只能出现一个设备,不然出现多个设备的话无法进行分压操作。这一点也就给了很多人设计一个特殊电路的可乘之机。但是我并不是如此

        • 首先,我们判断电路开端是否含有VCC信息,如果有,就设置电路初始电压为220V,反之为0V,GND判断同理。

        • 然后读取所有设备信息,包括控制器和被控制器。按照从电路开端到电路接地端的方向一步一步进行处理,并且令下一个设备的输出电压等于上一个设备的输出电压。这样就能得到所有设备的输入电压和输出电压。

        • 其次,获取了输入电压和输出电压后,就能用前者与后者的差计算出该设备的电压,再根据该设备的状态计算方式计算出它的转速或者亮度等状态信息。

        • 最后,对设备信息进行排序输出。到此,这道题目我们就解决了。

        UML类图

      3. 遇到的困难:

        按照刚才提供的设计思路可以解决大多数单一串联电路的情况,但是唯独有一种情况不能解决。

        开关在受控设备后

        因为,开关在受控设备后的时候会出现,受控设备已经获取到了输入和输出电压,但是开关却是断连的情况。但是受控设备的电压差已经计算出来了,也就是状态也被确定了。所以我们需要一些特殊处理。

        遍历所有开关

        确保所有开关都闭合再输出,如果有一个开关不闭合那就将受控设备的输入电压设定为0V,再进行输出。这样就能解决刚才的问题。

    • 第六次题目集

      1. 题目:

        此次题目集,加入了并联电路,并联电路可以由多个串联电路组成。每一条串联电路上可以有多个设备,并且新增了一个设备(落地扇),还为每个设备都赋予了电阻这个属性。使得整个电路系统更加符合现实中的情景。正是因为加入了电阻,才让整条电路具有了嵌入多个设备的条件,因为这样我们才可以正常的去计算每个设备的分压。

      2. 设计思路:

        我将这道题的解法分为八个部分:

        • 第一步:读入所有信息

        • 第二步:找到并联电路含有的所有串联电路,并处理串联电路:

          假设该并联电路包含an条串联电路,那就从第a1条串联电路开始遍历这n条串联电路,如果该串联电路是连通的(所有开关都闭合),那就将该串联电路的连通度标记为1,否则标记为0,并遍历该串联电路上的所有设备,将有电阻的设备的阻值相加,得到总电阻。

        • 第三步:将该并联电路转换为等效的串联电路,由于第二步已经获取了n条串联电路的总电阻,将所有连通度为1的串联电路的电阻倒数相加再取倒数,便能得到该并联电路的等效电阻。

        • 第四步:遍历该总电路上的所有设备(包括并联电路),将所有设备的电阻值相加,得到总电路电阻。

        • 第五步:再遍历该总电路上的所有设备(包括并联电路),将所有设备的电阻值与总电路电阻求比,并与总电路电压相乘,得到每个设备的分压。

        • 第六步:再一次找到并联电路含有的所有串联电路,并处理串联电路中的所有设备:

          由于第二步我们已经得到了n条串联电路的总电阻,所以此时遍历所有设备求其电阻与总电阻之比,并与第五步得到的并联电路分压相乘,得到并联电路上的串联电路的各个设备的分压。

        • 第七步:根据得到的每个设备的分压计算其对应的状态(转速、亮度)。

        • 第八步:对每个设备进行排序,并输出。

        在上面的步骤中,体现出要想获取分压,得先获得各条串联电路的总电阻。也就是设备分压和总电阻不可能在一次循环中就能被获取。所以每一条电路我们都需要走上两遍,并且存在在样的规律:

        遍历次数=总电路数×2+并联电路数×2

        UML类图:

      3. 遇到的困难:

        困难居然出在排序上,好吧,我确实不清楚如何让它们按照开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇的顺序依次输出。但是我可以换个方法,我先让所有设备按照序号排序。

        controlledDevices.sort(Comparator.comparingInt(ControlledDevice::getNumber));
        devices.sort(Comparator.comparingInt(Device::getNumber));
        

        让它们的顺序变得有序,但是名称是无序的,这样就够了。

        比如,设备信息原始的顺序是:

        D2,A1,D4,D3,D1,A4,B3,A2,B1,B4,B2,A3

        那么排序后的顺序应该是这样的:

        (A1|D1|B1),(A2|D2|B2),(A3|D3|B3),(A4|D4|B4)

        其中“|”表示前后顺序随机

        这个时候,只需要一点暴力的手段。写上几个循环,每一次都完整的把设备都遍历一遍,并且判断设备总类是否是需要输出的,如果是就输出,如果不是,就不输出。这样调整不同设备的循环的位置,就可以实现对名称排序了。挺笨的了

        😢

        但是能实现这个功能吧,也不是毫无用处。

      4. 代码分析:

        Class OCavg OCmax WMC
        ControlledDevice 1 1 2
        Controller 1 1 4
        Device 1 1 18
        Fan 1 1 4
        FanOfA 2 5 8
        FanOfD 1.5 3 6
        FilamentLamp 1.67 3 5
        FluorescentLamp 1.33 2 4
        Lamp 1 1 3
        ParallelCircuit 1 1 6
        SeriesCircuit 1 1 4
        SwitchOfF 2.2 7 11
        SwitchOfK 1.2 2 6
        SwitchOfL 1 1 5
        TotalCircuit 1 1 14
        Package v(G)avg v(G)tot
        3.25 276
        Module v(G)avg v(G)tot
        newpta6 3.25 276
        Project v(G)avg v(G)tot
        project 3.25 276

        好吧,惨不忍睹


以下是一些投机取巧

  1. 在改变开关状态的时候,我并没有使用布尔变量来表示开关的开闭。而是使用int类型的数据。首先给开关的状态赋值为0,之后每遇到同一个开关的输入信息,状态的赋值就加1,在最后判断开关状态时,对该值模2取余,如果余数为0,那开关就是断开的,如果余数为1,那开关就是闭合的。

  2. 电路系统中的每一种电路我都赋予了它一种属性——是否连通:

    串联电路上的每一个开关闭合则连通;

    并联电路上的只要存在一个串联电路连通,那并联电路也联通;

    总电路上的所有开关闭合且并联电路连通,那总电路也连通。

    连通则赋值为1,不连通则赋值为0。所以判断并联电路是否连通只需要把该并联电路包含的所有串联电路的连通度相加,若为0则为不连通,若大于0则为连通。

    我为什么这么做呢?

    因为这样的话,我可以把所有的开关一起等效为一个连接在总电路上的总开关,只有这个总开关闭合(也就是并联电路和总电路都是连通的),总电路才是联通的。

以上是一些投机取巧


  • 总结

    • 自我总结

      又是三次题目集,我好像敲代码的能力是提高了。设计能力稍有改善,但还是捉襟见肘。现在的代码量都已经上千行了,却还是没有一个很好的设计能力。到底是什么耽误了我的学习,Java课我也认真听,我也会上网课,虽然我可以拿到题目的满分,但是如果对代码也有评分的话,那我估计得完蛋。看来我还需要多学一些设计的思想,很多东西要上手了才会知道怎么用。我感觉我一直都在写很基础的代码。好的工具不用,怎么干得了好活呢?

    • 踩坑心得

      1. 我觉得题目里面有句话很模糊,但是又没有错,感觉很多人都是被这句话给迷惑了:

        只要不造成短路而产生无穷大的电流烧坏电路,都是合理情况,在测试点的考虑范围之内。本次大作业不考虑短路的情况,测试点中不包括短路的电路。

        对于这段话,请看下面这个样例:

        #T1:[IN K1-1] [K1-2  D2-1] [D2-2 OUT]
        #T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
        #M1:[T1 T2]
        #T3:[VCC M1-IN] [M1-OUT A3-1] [A3-2 GND]
        #K2
        #K1
        end
        

        很明显,这个样例中的并联电路处于短路状态呢,那是不是就不考虑这种情况了?不要忘了,不考虑短路的情况还包含一个前提条件:

        产生无穷大的电流烧坏电路。

        请问,这会产生无穷大的电流吗?会烧坏电路吗?

        当然不会

        这个是短接,属于短路的一种。被短接的部分就相当于是导线了,也就是该并联电路的等效电阻为0欧姆,就不会产生分压,那何来烧坏电路之说呢?

        我并不知道测试点里有没有这个情况,但是我觉得我的理解很到位。

      2. 还有,我开始居然想用输入引脚和输出引脚的电势差来计算分压,然后发现真的是大可不必,前面的方法是用来应对电路模拟程序-1的,现在已经有电阻了,直接计算分压才是正解!

      3. 本次题目给的样例只有3个,然后测试点毫无提示。这真的是很折磨也很费头发的两个因素,想来很多人差两三个没过的原因就在此处了吧。毕竟完全靠自己摸爬滚打,没有任何提示,所有人都一样。所以,我就疯狂写样例,前前后后用了不下五十个自己写的样例,才一举拿下这道题。所以测试真的很重要啊!

    • 课程建议

      1. 发题的时间尽量固定一下。
      2. 老师们出的题目真的很好很好,很新颖、很有难度也很能检测学生水平。但是有些学生一次没做出来可能后面直接就不做了,有些学生到题目结束也不知道自己为什么错。所以我希望当题目结束一段时间后,老师可以公布一些多数学生存在疑问的测试点供大家修改bug。

与OOP课第二阶段总结相似的内容:

OOP课第二阶段总结

OOP课第二阶段总结 前言 作为第二次3+1的总结,明显感受到了此次题目集越来越复杂,结合了实际的物理知识来解决现实中的电路问题。因为电路可以一直扩展下去,情况千变万化,难以像上次题目集一样找到一个呆板的做法。这次题目集,让很多人连题目都无法理解,代码也是无从下手,因为这些人根本不知道如何去设计,如

OOP课第三阶段总结

OOP课第三阶段总结 前言: 我想说的第一句是:”我感受到了设计上的极大缺陷“,从一开始,我完全就忽略了引脚的存在。因为在第二阶段中,家电模拟大作业一、二在不需要考虑引脚的情况下也可以完成。但是当来到第三次,出现了互斥开关,因为互斥开关的特殊性,它具有1、2、3三个引脚,并且连接方式多种多样,所以再

OOP第二阶段题集总结

一.前言 知识点:考察继承和多态为多,其中还涉及迭代器的使用,在每个题集中都有一个综合性题目设计多方面知识点考试,有List类和HashMap的使用以及正则表达式的运用,并且注重考查设计,理解类与类之间的关系进行合理设计,其中也要遵循我们所学的单一职责,开闭原则,迪米特法则等。 题量:第四次题集和第

oop课程4-6次作业小结

目录(1)前言(2)设计与分析第四次作业(答题判题程序-4)新增多选类新增填空类第五次作业(家居强电电路模拟程序-1)Element类控制设备开关#分档调速器#受控设备白炽灯#日光灯#吊扇#计算电压(家庭电路类)第六次作业(家居强电电路模拟程序-2)Element类Light类Fan类(3)采坑心得

深入理解 C++ 中的多态与文件操作

C++ 多态 多态(Polymorphism)是面向对象编程(OOP)的核心概念之一,它允许对象在相同操作下表现出不同的行为。在 C++ 中,多态通常通过继承和虚函数来实现。 理解多态 想象一个场景,你有一个动物园,里面有各种动物,如猫、狗、鸟等。每个动物都有自己的叫声。使用面向对象编程,我们可以创

C++ 多级继承与多重继承:代码组织与灵活性的平衡

C++ 多级继承 多级继承是一种面向对象编程(OOP)特性,允许一个类从多个基类继承属性和方法。它使代码更易于组织和维护,并促进代码重用。 多级继承的语法 在 C++ 中,使用 : 符号来指定继承关系。多级继承的语法如下: class DerivedClass : public BaseClass1

7.0 Python 面向对象编程

python是一种面向对象的编程语言,面向对象编程(Object-Oriented Programming,OOP)是一种编程思想,其核心概念是“对象”。对象是指一个具有特定属性和行为的实体,而面向对象编程就是通过对这些实体进行抽象、分类、封装和继承等操作,来实现程序的结构和逻辑。在python中,我们可以通过定义类、创建实例和调用方法等方式,来实现面向对象编程的思想,从而编写出更加灵活、可扩展、

[转帖]JVM 系列 - 内存区域

一、对象在JVM中的表示: OOP-Klass模型 https://www.jianshu.com/p/424a920771a3 写的很赞。 注意:OOP-Klass是hotspot的JVM实现原理,其他JVM的实现可能不一样。、 OOP表示java实例,Klass表示class。 Klass: 包

Netty-介绍-1

Netty介绍和应用场景 要求 已经掌握了 主要技术构成: Java OOP 编程、 Java 多线程编程、 Java IO 编程 、 Java 网络编程、 常用的Java 设计模式(比如 观察者模式 ,命令模式,职责链模式 )、 常用的数据结构(比如 链表) Netty的介绍 1、Netty 是由

继承,super,重写,多态,抽象,接口

继承,super,重写,多态,抽象,接口 继承 extends 用于表示两个类之间的继承关系,继承是OOP的四大特性之一,他允许一个类(称之为子类或派送类) 继承另一个类(称之为父类或基类)的变量和方法,子类可以复用父类的方法和变量,也可以添加和覆盖父类的方法和变量 extends的基本语法 使用e