OOP课第二阶段总结
OOP课第二阶段总结
前言
作为第二次3+1的总结,明显感受到了此次题目集越来越复杂,结合了实际的物理知识来解决现实中的电路问题。因为电路可以一直扩展下去,情况千变万化,难以像上次题目集一样找到一个呆板的做法。这次题目集,让很多人连题目都无法理解,代码也是无从下手,因为这些人根本不知道如何去设计,如何去完成电路上的整个过程,也就是没有抓到本质。
目前题目集只迭代了两次,从最开始的单一串联电路、单一设备,到现在的由多个串联电路组成的并联电路、多个设备,这两次迭代已经可以看出这次题目集的复杂性。再经历两次迭代后,将完整的模拟电路中可能出现的所有情况(多并联、多串联、短路、双向开关......),所以对我们前期的设计思路要求缜密且严谨。
而且在第二次迭代中,题目采取了不提示测试点的手段,让很多学生举步维艰,测试了N个由自己或同学创造的样例后仍然找不到错误,最终停留在了88、91、94分。由于学生代码设计上的缺陷以及题目不提示测试点的手段,使得很多人痛不欲生,”明明别人的样例我都过了,可为什么他拿到了100而我只有94呢?“,在这样的自我怀疑中不断地寻找错误。运气好的同学也许再测试了一些样例后可以找到错误,可运气不好的同学可能等到题目结束的最后一刻都没有找到一丁点错误,可是事实就是他错了,但是错得看起来天衣无缝,无法叫人发现。
并且我统计了前六次题目集得提交以及通过情况:
由此不难看出,题目集的实际通过率(通过人数/考试人数)处于0.2~0.5这个区间,其中最难的一次为题目集三,实际通过率仅为0.178,但提交数量却是最多的,三百人提交了将近一万三千份答卷。学生在经历了这么多次练习后,通过率的总体趋势却是起起伏伏,当然这也和题目难度相关。题目集一和五都是作为两次大迭代的开端,故而各个数据都非常相似,由此我们也许可以预测一下,下一次题目集的通过率可能会达到第二次迭代最低。
正文
第四次题目集
从上表可以看出,在经历了第三次题目集的大洗劫后,居然得到了很大的改善,不仅提交量减少了,而且提交通过率还提高了不少。也许是因为同学在第三次题目集下了很大的功夫还吃了亏,将代码的质量提高了不少。但这并不是今天的重点。
UML类图:
第五次题目集
题目:
这次题目集便是第二次大迭代的开端,主要内容为计算单一串联电路上的设备状态
题目主干:
设计一个智能家居强电电路模拟系统:
模拟的控制设备包括:开关、分档调速器、连续调速器。
模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
并且提供了四次迭代的区别:
迭代1:只有一条线路,所有元件串联
迭代2:线路中包含一个并联电路
迭代3:线路中包含多个串联起来的并联电路
迭代4:并联电路之间可能出现包含关系这就很考验学生的总体设计能力,不能只顾眼前的题目集,还要考虑到为题目集的迭代做好准备。
设计思路:
因为这次题目的设备并没有电阻,所以无法使用正常的根据电阻求分压的方法来计算设备状态,也因此,电路中只能出现一个设备,不然出现多个设备的话无法进行分压操作。这一点也就给了很多人设计一个特殊电路的可乘之机。但是我并不是如此。
首先,我们判断电路开端是否含有VCC信息,如果有,就设置电路初始电压为220V,反之为0V,GND判断同理。
然后读取所有设备信息,包括控制器和被控制器。按照从电路开端到电路接地端的方向一步一步进行处理,并且令下一个设备的输出电压等于上一个设备的输出电压。这样就能得到所有设备的输入电压和输出电压。
其次,获取了输入电压和输出电压后,就能用前者与后者的差计算出该设备的电压,再根据该设备的状态计算方式计算出它的转速或者亮度等状态信息。
最后,对设备信息进行排序输出。到此,这道题目我们就解决了。
UML类图
遇到的困难:
按照刚才提供的设计思路可以解决大多数单一串联电路的情况,但是唯独有一种情况不能解决。
开关在受控设备后
因为,开关在受控设备后的时候会出现,受控设备已经获取到了输入和输出电压,但是开关却是断连的情况。但是受控设备的电压差已经计算出来了,也就是状态也被确定了。所以我们需要一些特殊处理。
遍历所有开关
确保所有开关都闭合再输出,如果有一个开关不闭合那就将受控设备的输入电压设定为0V,再进行输出。这样就能解决刚才的问题。
第六次题目集
题目:
此次题目集,加入了并联电路,并联电路可以由多个串联电路组成。每一条串联电路上可以有多个设备,并且新增了一个设备(落地扇),还为每个设备都赋予了电阻这个属性。使得整个电路系统更加符合现实中的情景。正是因为加入了电阻,才让整条电路具有了嵌入多个设备的条件,因为这样我们才可以正常的去计算每个设备的分压。
设计思路:
我将这道题的解法分为八个部分:
第一步:读入所有信息
第二步:找到并联电路含有的所有串联电路,并处理串联电路:
假设该并联电路包含an条串联电路,那就从第a1条串联电路开始遍历这n条串联电路,如果该串联电路是连通的(所有开关都闭合),那就将该串联电路的连通度标记为1,否则标记为0,并遍历该串联电路上的所有设备,将有电阻的设备的阻值相加,得到总电阻。
第三步:将该并联电路转换为等效的串联电路,由于第二步已经获取了n条串联电路的总电阻,将所有连通度为1的串联电路的电阻倒数相加再取倒数,便能得到该并联电路的等效电阻。
第四步:遍历该总电路上的所有设备(包括并联电路),将所有设备的电阻值相加,得到总电路电阻。
第五步:再遍历该总电路上的所有设备(包括并联电路),将所有设备的电阻值与总电路电阻求比,并与总电路电压相乘,得到每个设备的分压。
第六步:再一次找到并联电路含有的所有串联电路,并处理串联电路中的所有设备:
由于第二步我们已经得到了n条串联电路的总电阻,所以此时遍历所有设备求其电阻与总电阻之比,并与第五步得到的并联电路分压相乘,得到并联电路上的串联电路的各个设备的分压。
第七步:根据得到的每个设备的分压计算其对应的状态(转速、亮度)。
第八步:对每个设备进行排序,并输出。
在上面的步骤中,体现出要想获取分压,得先获得各条串联电路的总电阻。也就是设备分压和总电阻不可能在一次循环中就能被获取。所以每一条电路我们都需要走上两遍,并且存在在样的规律:
遍历次数=总电路数×2+并联电路数×2
UML类图:
遇到的困难:
困难居然出在排序上,好吧,我确实不清楚如何让它们按照开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇的顺序依次输出。但是我可以换个方法,我先让所有设备按照序号排序。
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)
其中“|”表示前后顺序随机
这个时候,只需要一点暴力的手段。写上几个循环,每一次都完整的把设备都遍历一遍,并且判断设备总类是否是需要输出的,如果是就输出,如果不是,就不输出。这样调整不同设备的循环的位置,就可以实现对名称排序了。挺笨的了
但是能实现这个功能吧,也不是毫无用处。
代码分析:
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 好吧,惨不忍睹。
以下是一些投机取巧
在改变开关状态的时候,我并没有使用布尔变量来表示开关的开闭。而是使用int类型的数据。首先给开关的状态赋值为0,之后每遇到同一个开关的输入信息,状态的赋值就加1,在最后判断开关状态时,对该值模2取余,如果余数为0,那开关就是断开的,如果余数为1,那开关就是闭合的。
电路系统中的每一种电路我都赋予了它一种属性——是否连通:
串联电路上的每一个开关闭合则连通;
并联电路上的只要存在一个串联电路连通,那并联电路也联通;
总电路上的所有开关闭合且并联电路连通,那总电路也连通。
连通则赋值为1,不连通则赋值为0。所以判断并联电路是否连通只需要把该并联电路包含的所有串联电路的连通度相加,若为0则为不连通,若大于0则为连通。
我为什么这么做呢?
因为这样的话,我可以把所有的开关一起等效为一个连接在总电路上的总开关,只有这个总开关闭合(也就是并联电路和总电路都是连通的),总电路才是联通的。
以上是一些投机取巧
总结
自我总结
又是三次题目集,我好像敲代码的能力是提高了。设计能力稍有改善,但还是捉襟见肘。现在的代码量都已经上千行了,却还是没有一个很好的设计能力。到底是什么耽误了我的学习,Java课我也认真听,我也会上网课,虽然我可以拿到题目的满分,但是如果对代码也有评分的话,那我估计得完蛋。看来我还需要多学一些设计的思想,很多东西要上手了才会知道怎么用。我感觉我一直都在写很基础的代码。好的工具不用,怎么干得了好活呢?
踩坑心得
我觉得题目里面有句话很模糊,但是又没有错,感觉很多人都是被这句话给迷惑了:
只要不造成短路而产生无穷大的电流烧坏电路,都是合理情况,在测试点的考虑范围之内。本次大作业不考虑短路的情况,测试点中不包括短路的电路。
对于这段话,请看下面这个样例:
#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欧姆,就不会产生分压,那何来烧坏电路之说呢?
我并不知道测试点里有没有这个情况,但是我觉得我的理解很到位。
还有,我开始居然想用输入引脚和输出引脚的电势差来计算分压,然后发现真的是大可不必,前面的方法是用来应对电路模拟程序-1的,现在已经有电阻了,直接计算分压才是正解!
本次题目给的样例只有3个,然后测试点毫无提示。这真的是很折磨也很费头发的两个因素,想来很多人差两三个没过的原因就在此处了吧。毕竟完全靠自己摸爬滚打,没有任何提示,所有人都一样。所以,我就疯狂写样例,前前后后用了不下五十个自己写的样例,才一举拿下这道题。所以测试真的很重要啊!
课程建议
- 发题的时间尽量固定一下。
- 老师们出的题目真的很好很好,很新颖、很有难度也很能检测学生水平。但是有些学生一次没做出来可能后面直接就不做了,有些学生到题目结束也不知道自己为什么错。所以我希望当题目结束一段时间后,老师可以公布一些多数学生存在疑问的测试点供大家修改bug。
OOP课第二阶段总结的更多相关文章
- php学习笔记——学习路线图记录
PHP学习路线图 最全PHP自学指南 W3Cschool小编 2018-04-24 15:23:51 浏览数 (5381) 分享 收录专辑 对于广大零基础的PHP自学者,往往不知道如何系统的学习PHP ...
- 优化MySchool数据库设计之【巅峰对决】
优化MySchool数据库设计 之独孤九剑 船舶停靠在港湾是很安全的,但这不是造船的目的 By:北大青鸟五道口原玉明老师 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识 ...
- 第三章SQL编程
本章目标: 1.使用变量 2.输出语句 3.数据类型转换 4.逻辑控制语句 5.批处理 一.变量 1.什么是变量呢? 变量是存储数据的容器 T-SQL中的变量分为局部变量和全局变量 2.局部变量 局部 ...
- 万能的 SQL编程
简介:T-SQL语句创建库.创建表和听.和添加约束等.T-SQL是数据库结构化查询语言,常见的增加.删出.修改.查询.创建库和创建表的语句,还支持定义变量.输出语句.逻辑控制语句(IF.CASE.WH ...
- 自从学了SQL编程,哪里不会点哪里!!!
在学习SQL编程前,先给大家分享几个段子吧,咱先乐呵乐呵! <桃花庵--程序员版> 写字楼里写字间,写字间中程序员:程序人员写程序,又将程序换酒钱: 酒醒只在屏前坐,酒醉还来屏下眠:酒醉酒 ...
- java第六课 oop
java oop 1.面向过程的结构化程序设计弊端:方法和数据结构都是毫无规律的定义在程序中任何位置 方法定义和方法要处理的数据结构也都是分开定义 2.对象:每new一次,就创建1个新对 ...
- 第四课 OOP封装继承多态解析,接口抽象类选择 2019-04-21
父类 xx = new 子类(); xx.method(); 1 普通方法由编译时决定(左边) --- 提高效率 2 虚方法(virtual) 由运行时决定-- -多态,灵活 3 抽象方法由运行时决 ...
- OO课程第二阶段(实验和期中试题)总结Blog2
OO课程第二阶段(实验和期中试题)总结Blog2 前言:学习OOP课程的第二阶段已经结束了,在此进行对于知识点,题量,难度的个人看法. 学习OOP课程的第二阶段已经结束了,较第一次阶段学习难度加大,学 ...
- Python之路第一课Day6--随堂笔记(面向对象 )
本节内容: 1. 面向对象编程介绍 2. 为什么要用面向对象进行开发? 3. 面向对象的特性:封装.继承.多态 4. 类.方法 一.面向过程 VS 面向对象 1. 编程范式 编程是 程序 员 用 ...
- Scala 深入浅出实战经典 第49课 Scala中Variance代码实战(协变)
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
随机推荐
- Pytorch风格迁移代码
最近研究了一下风格迁移,主要是想应用于某些主题节日时动态融合背景,生成一些抽象的艺术图片,这里给大家分享一个现成的代码,我本地把环境搭建好后跑了试试,有兴趣的可以直接拿去运行: 1 import to ...
- tomcat 服务版本内存设置
1. 安装服务,如需指定java路径,需要在service.bat 中修改, 如下图 其中 pa代表当前目录 2. 安装服务, service.bat install 服务名,如下图示例 3. 内存设 ...
- uniapp小程序页面实现元素与胶囊进行居中对齐
无论是否为uni,关键在于获取胶囊中点的位置,如果是原生小程序根据小程序文档获取,其余逻辑处理是一致的 代码语法都只是技术选择,重点是逻辑处理,对于技术的运用,代码技术好比是积木,好的程序就是好的组合 ...
- react中<link>和<navlink>区别
两者都是实现路由的跳转.但 点击<Link>时,url会更新,组件会被重新渲染,但是页面不会重新加载...使用to链接组件时,它的值既可是字符串,也可以是location对象(包含path ...
- 【Oracle】 管道函数pipelined function简单的使用
Oracle 管道函数pipelined function简单的使用 如果在函数(function)中加关键字 pipelined,就表明这是一个oracle管道函数,其返回值类型必为 集合,体现出来 ...
- HarmonyOS NEXT应用开发案例——行程地址交换动画
介绍 本示例介绍使用显式动画 animateTo 实现左右地址交换动画.该场景多用于机票.火车票购买等出行类订票软件中. 效果预览图 使用说明 加载完成后显示地址交换动画页面,点击中间的图标,左右两边 ...
- 一首歌的时间,手把手搭建基于FC的网站
简介: 不是杰伦的那一首歌啦~ 部署网站 说好不哭 在接触serverless架构之前,我们如果想实现上线一个Web网站,就要在开发前期经过操作很多冗杂但又必须的步骤,不少小白可谓是快速的从入门到退坑 ...
- 一看即会:Serverless 应用开发的 7 个实战小技巧
简介:干货满满,马住收藏! Serverless 应用开发的 7 个经验心得 作者说:Serverless 架构下的应用开发,与传统架构的应用开发还是有比较大的区别点的,例如天然分布式架构会让很 ...
- 2018-8-10-win10-uwp-如何开始写-uwp-程序
title author date CreateTime categories win10 uwp 如何开始写 uwp 程序 lindexi 2018-08-10 19:16:50 +0800 201 ...
- C#的基于.net framework的Dll模块编程(四) - 编程手把手系列文章
这次继续这个系列的介绍: 一.命名空间的起名: 对于C#来说,一般命名空间的建议是:公司名(或个人名称).产品名.分类名,比如我这边是用的这个:Lzhdim.LPF.Helper,意思是个人名Lzhd ...