PTA题目集7-8的总结

news/2024/10/5 8:49:51/文章来源:https://www.cnblogs.com/homework-33/p/18273914

PTA题目集7-8的总结

1.前言:

2.设计与分析:

3.踩坑心得:

4.改进意见:

5.总结

1.前言:

  PTA题目集7新增了互斥开关,窗帘,多并联电路和多串联电路。由于之前的输入信息中设备的引脚没有作用,所以我的正则表达式只用来提取设备的名字。而互斥开关有三个引脚,不同引脚的电压也不一样,所以这次题目集要提取引脚的编号。因此我打算沿用上次题目集的代码,修改Main函数中的部分代码。

  PTA题目集8新增了二极管,并联中包含并联。输出方式也改变了,要输出每个设备的各引脚电压,如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”。讲真,看完题目我心都凉了,真的很复杂。在和舍友讨论后,我大概理解处理引脚电压了。由于我PTA6的代码只能识别到主电路中有M就找并联电路的信息,不能识别并联中的串联是否有并联,只能处理一次并联信息。如果我在上一次代码中加入了识别并联中的串联是否有并联的代码,只是面向结果编程。所以我决定重写,让代码能实现无论多少层并联都能处理。

2.设计与分析:

题目集7

  1.输入:

 由于本次题目集有多并联电路和多串联电路,会出现多个T,M的电路名字需要识别,所以我用HashMap<String, String>存储T,M电路信息(key存储电路名字,value存储电路信息)。控制设备的调节信息还是用ArrayList存储,但是需要用字符串subString(1,str.length()),不存储#。

  2.分析代码

  (1)代码复杂度:

  由图中可以看出,只有我自己创建的处理设备的类和Main类代码复杂,其他设备类都较为简单。

 

    

 

  由图中可以看出,Main函数的方法少,但是复杂,主要是我设计了一个方法来处理电路信息,比如创建设备,分配电压等。

 

             

  (2)设计思路:

    

  由类图可以看出本次题目集与上次题目集的设计的类差别不大,只是在Main函数中计算电阻及电压的方式不同。本次题目集先用正则表达式将主电路的电阻计算出来,如果主函数有T,正则表达式提取出串联的名字,通过hashmap的get方法获取串联电路信息,再使用方法计算这条电路的电阻;如果主函数有M,正则表达式提取出并联的名字,通过hashmap的get方法获取并联电路信息,通过正则表达式提取并联部分的各串联电路的名字,再依次使用方法计算各条电路的电阻。重复此操作,传电压和电路信息,创建设备,输入设备信息。

  控制设备新增了互斥开关,有三个引脚,但是输出1,2引脚接通状态信息。因此如果检测到互斥开关的1,2引脚,判断状态,如果是1,2接通,则该设备的setOpen()方法传1,否则传0。

  受控设备新增了窗帘,但是窗帘的打开比例是由整个电路的室内灯光的光照强度和设备电压决定的。因此,我设置了一个全局变量用来记录整个电路的室内灯光的光照强度,遇到白炽灯或者是日光灯就加上设备的光照强度。处理完电路信息后,再设置窗帘的打开比例。

  (3)重点代码分析:

  与上次题目集相比,我修改了正则表达式。上一次题目集的正则表达式用在了Main函数的方法中,用来识别设备计算电阻或是分配电压。考虑到本次题目集有多并联电路和多串联电路,因此我设计了两个正则表达式识别信息,一个用来识别受控设备和控制设备,一个用来设别串联电路和并联电路。本次题目集的第一个正则表达式识别到了T或是M,则用Main函数的方法计算电压;第二个正则表达式先提取设备的名字,如果设备的名字包括H,再提取设备的编号,再加上这个设备的电阻。

正则表达式
         Pattern p = Pattern.compile("\\s([^-]*)-IN\\]\\s\\[[^-]*-OUT");Matcher m = p.matcher(mainCircuit);Pattern p1 = Pattern.compile("\\s([^-]*)-(\\d)\\]\\s\\[[^-]*-(\\d)");Matcher m1 = p1.matcher(mainCircuit);

  在计算电压时,检测到互斥开关H后,由于互斥开关输出的是1,2引脚和1,3引脚的电阻不一样的,开关状态不一样,会有多种情况。电路中可能会出现两次同一个互斥开关的信息,而输入信息中可能会出现切换互斥开关的信息,所以我设计了一个方法来检测在分析电路信息时遇到的互斥开关是否是接通的。如果互斥开关接通则判断两个引脚是否包含2,是则电阻+5,否则电阻+10。

判断互斥开关的状态
	public static int detection(String str) {Pattern p = Pattern.compile("\\s(H\\d*)-(\\d)\\]\\s\\[[^-]*-(\\d)");Matcher m = p.matcher(str);int count = 0;while (m.find()) {String name = m.group(1);for (int i = 0; i < list.size(); i++) {if ((list.get(i).substring(1,list.get(i).length())).equals(name)) {count++;}}if(m.group(2).equals("2")||m.group(3).equals("2")) {if (count % 2 == 0) {return 1;}else {return 0;}}if(m.group(2).equals("3")||m.group(3).equals("3")) {if (count % 2 == 0) {return 0;}else {return 1;}}}return -100;}

 题目集8

  (1)代码复杂度:

       

       

  (2)设计思路:

         从类图看,可以发现我新增了两个类:一个是计算串联部分电阻的类;一个是计算并联部分电阻的类,而这个类会使用计算串联部分电阻的类,通过计算并联电路的电阻公式得到此并联电路的电阻。如果它检测到并联中的小串联包含并联,会再创建一个计算该并联电阻的类,可以循环下去,计算并联中包含并联的更复杂的情况。

 

 

         从类图可看出,受控设备有两个double类型引脚,还有一个记录该设备电压的double类型的Pin。我先分配该设备的电压,再用set()方法设置该设备的前一个引脚的电压,后一个引脚的电压通过前一个引脚的电压减去该设备电压计算得到。

 

    考虑到互斥开关有三个引脚,因此设置了Pin1,2,3,Pin。控制设备的第一个引脚也是用set方法传参,Pin是通过information这个类来设置,得到经过该设备后的电压值,再去set后一个引脚的电压。上面的方法不适用于互斥开关,因为互斥开关有电阻。因此,如果是互斥开关,要检测第一个引脚的编号,再去set电压值。还要检测这条电路的互斥开关的引脚是1,2还是1,3,计算互斥开关的电压,再用第一个引脚的电压减去该设备电压从而计算出第二个引脚的电压。

 

 

  (3)重点代码分析:

  我设计的并联电路类可以处理多种情况,例如并联电路不通,并联电路短路,并联电路部分不通,并联电路全通,并联电路前面设备是否可通,并联电路是否包含并联电路。

并联电路类
 class Parallel {private double R;public double getR() {return R;}public void setR(double r) {R = r;}private HashMap<String, String> voltage ;private ArrayList<String> list;private HashMap<String, String> circuit;public Parallel(String name,ArrayList<String> list,HashMap<String, String> voltage,HashMap<String, String> circuit) {this.list=list;this.voltage=voltage;this.circuit=circuit;String circuit1 = circuit.get(name);ArrayList<Double> resistance1 = new ArrayList<>();Pattern p = Pattern.compile("T\\d*");Matcher m = p.matcher(circuit1);int count=0;int count1=0;int flag=0;double R=0;while (m.find()) {String name1=m.group();//找到了T2String circuit2 = voltage.get(name1);//找到了T2后面的连接信息Pattern p1 = Pattern.compile("M\\d*");Matcher m1 = p1.matcher(circuit2);if(m1.find()) {//检测大并联中是否含有小并联Concatenation concatenation=new Concatenation(circuit2,list);Parallel parallel=new Parallel(m1.group(),list, voltage, circuit);if(parallel.getR()==0) {//并联直接走,只有开关if(concatenation.getR()==0) {//无电压,大并联短路flag=1;}else if(concatenation.getR()==-1){//并联不通resistance1.add(0.0);}else {resistance1.add(concatenation.getR());}}else if(parallel.getR()==-1) {//并联不通resistance1.add(0.0);}else {if(concatenation.getR()==-1) {//小并联前面部分不通resistance1.add(0.0);}else {resistance1.add(parallel.getR()+concatenation.getR());}}}else {if ((!circuit2.contains("D")) && (!circuit2.contains("A")) && (!circuit2.contains("R"))&& (!circuit2.contains("B"))) {		if(circuit2.contains("K")&&state(circuit2)) {//有一条只含开关并可通行的电路flag = 1;}}Concatenation concatenation=new Concatenation(circuit2,list);if(concatenation.getR()==-1) {resistance1.add(0.0);//0则不通}else {resistance1.add(concatenation.getR());}}}if(flag==1) {//有一条只含开关并可通行的电路setR(0);}else {for(int i=0;i<resistance1.size();i++) {if(resistance1.get(i)!=0) {R+=1/(resistance1.get(i));}}if(R==0) {//并联电路不通setR(-1);}else {//有电阻setR(1/R);}}}

    

3.踩坑心得:

 1.在写完PTA7的代码后,我进行测试,发现同一个互斥开关的信息输出了两次。通过调试发现,并联电路中使用同一个互斥开关时,我的代码检测到了设备就会创建,因此并联电路中两条电路出现同一个设备名时,会创建这个设备两次。因此,我在创建设备前先判断这个设备是否已经创建了。

互斥开关
 else if (name.contains("H")) {int flag3=0;int count = 0;for(int i=0;i<device1.size();i++) {if(name.equals(device1.get(i).getName())) {flag3=1;break;}}if(flag3==0) {d1 = new Mutex_switch();for (int i = 0; i < list.size(); i++) {if ((list.get(i).substring(1,list.get(i).length())).equals(name)) {count++;}}if(count%2==0) {((Mutex_switch) d1).setOpen(1);}else {((Mutex_switch) d1).setOpen(0);}device1.add(d1);device1.get(device1.size() - 1).setName(name);}}

   2.我以为PTA8只要考虑互斥开关和二极管的引脚顺序,而其他设备的引脚默认1在前,2在后。直到发现提交后有一个测试样例中包含 D1-2] [D1-1 ,才发现所有设备的引脚都不做限制,哪个编号在前,哪个是输入引脚。

  如果按照我当时的方法,就会导致引脚电压设置错位和引脚电压为负数的情况。

   3.还是因为上面的测试样例,我发现部分设备的引脚与正确输出差了1,我觉得是double类型精度值问题,但是解决这个问题非常麻烦。因此我上网查了double类型加法如何避免精度值造成不准。由此,在Main函数写下了一个double类型的加法方法。

加法方法
 	public static double subtractionDouble(double m1, double m2) {BigDecimal p1 = new BigDecimal(Double.toString(m1));BigDecimal p2 = new BigDecimal(Double.toString(m2));if(Math.abs(p1.subtract(p2).doubleValue())<Math.pow(1, -5)) {return 0.0;}else {return p1.subtract(p2).doubleValue();}}

4.改进意见:

      1.在PTA7中,我先在Main函数中求出主电路的总电阻,再去分配电压。因此我使用了两次相同的正则表达式,现在我觉得过于累赘了。有两种方法处理,第一种是将正则表达式移动到计算电压的方法中,这样条理清楚,并且在下一次使用电阻是方便调用;第二种方法采取我PTA8的方法处理,逻辑就很清晰,但是我放到PTA7中测试时还是错了三个测试点。

  2.由于PTA8的发布时间在考试周,并且题目较难,所以这次我花费的时间没之前多,分数也比之前低。我听舍友说并联电路中的各个串联电路中,如果有电路不通,那这条电路的最后一个引脚的电压要和此并联的已通串联的最后一个引脚的电压一样。我觉得这种情况在我的代码的基础上太难实现。因为这不但要先获取到已通电路的最后一个引脚的电压,还得记住这个电压是此并联的电压。我希望老师能公布测试点或者展示优秀代码,让我学习如何处理。

  3.PTA8的控制设备分档调速器和连续调速器没有写判断引脚序号的,新增的测试点发现了,但是只修改了开关的,提交发现还是没有加分,等之后写补练时再全修改了,看看能不能多加几分。🤪

5.总结:

 1.家具强电电路模拟程序终于结束了,我真的能感觉到一次比一次难,还是佩服老师的出题思路和我自己能写出代码来。我从一开始接触这种题型的懵圈,通过一次次学习,到了看到题目能很快想出自己的思路,感觉我的能力真的得到了提高。不过我每次有思路后写代码很快,但是第一次代码的得分都不高,只能慢慢的改代码了。

  2.老师给的测试样例越来越少,关于PTA8题目集我有很多疑问,但是没有相关解释或是测试样例给我解疑。如果之后的学习还是使用PTA平台的话,我希望能多给几个测试样例。最离谱的还是老师在距离截止时间前一天新增了四个测试点,还是没有提示的测试点。一开始我还以为是测试样例,非常激动,一看PTA是测试点,人都傻了,总分还因此低了4分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/739204.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pycharm 动态绘图

_tkinter.TclError: Cant find a usable init.tcl in the following directories:解决办法: 1 打开报错地址所在文件 D:/Program Files/METACOMP/mlib/tcltk8/lib/tcl8.4/init.tcl: version conflict for package "Tcl": have 8.6.9, need exactly 8.4 2 修改init.t…

从零开始教你写一个MLIR Pass

笔者在去年写了一篇LLVM Pass的教程,现在从事MLIR的开发近1年了,写点教程回馈下社区。 MLIR(Multi-Level Intermediate Representation,多层中间表示)是LLVM之父(博士期间开发的LLVM)的Chris Lattner带领团队开发的编译器基础设施,其增强了 LLVM IR表达能力,而且其是关注P…

idm下载

获得百度网盘直链下载链接调用idm谷歌插件获得城盘直链下载链接调用idm谷歌插件 https://ctfile.qinlili.bid/当你的才华配不上你的野心,努力的时候到了!

Arthas进阶-笔记

《Arthas进阶》 学习目标类和类加载器相关的命令 monitor/watch/trace/stack等核心命令的使用 火焰图的生成 Arthas实战案例dump 作用 将已加载类的字节码文件保存到特定目录:logs/arthas/classdump/ 参数数名称 参数说明class-pattern 类名表达式匹配[c:] 类所属 ClassLoader…

域名、备案和HTTPS

有了域名后,可以方便其他人记住并访问12.域名、备案和HTTPS 有了域名后,可以方便其他人记住并访问,历史上不乏大企业花大价钱购买域名的:京东域名换成 JD.com,并且说是为了防止百度吸引流量,为什么? 唯品会买下域名 VIP.COM 或花费千万‍ 域名提供商 如果想要域名,得去…

陪玩app源码,加密算法中密钥生成和读取一览

陪玩app源码,加密算法中密钥生成和读取一览密钥生成与读取密码学随机数密码学随机数算法在安全场景中使用广泛,如:生成对称密钥、盐、iv等,因此相比普通的随机数算法(如线性同余),它需要更高强度的不可预测性,在Java中,使用SecureRandom来生成更安全的随机数,如下:pub…

陪玩小程序源码,不容错过的加密算法整理清单

陪玩小程序源码,不容错过的加密算法整理清单在开发陪玩小程序源码时,可采用的加密算法类型包含:对称加密对称加密算法,使用Cipher类即可,以广泛使用的AES为例,如下:public byte[] encrypt(byte[] data, Key key) {try {Cipher cipher = Cipher.getInstance("AES/CB…

【QT】工程库引用

创建多工程项目创建子项目UI窗体项目创建库工程项目引用库工程添加日志输出类5.1 需要添加特殊配置,否则编译会报错5.2 正确添加配置5.3 日志正常输出5.4 如果缺少5.1步骤,则报如下错误5.5 如果添加了5.1步骤,还是报The process was ended forcefully 找到项目文件,把debug…

陪玩系统源码,为守护系统安全增添更多助力

陪玩系统源码,为守护系统安全增添更多助力在开发陪玩系统源码时,可以通过加密、解密算法来提升系统的安全性,比较常见的加密、解密算法类型有:1、对称加密:速度快,可逆,常见DES,AES等2、非对称加密:速度慢,可逆,常见RSA等3、签名算法:唯一,不可逆,常见MD5,SHA,…

pycharm创建临时文件scatch file

JetBrains PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。 有时您可能需要创建临时注释或在项目上下文之外起草一些代码。为此,您可以使用临时文件和临时缓冲…

P5441

P5441 神仙题目。 tips:后面把 \(4\) 个点说成一个组。我们先考虑一个组怎么连才不是强联通的。一个点 A 向另外三个点 BCD 连一条有向边。在不满足第一种的情况下,BCD 向另一个点 A 连一条有向边。AB 之间连有向边,CD 之间连无向边,然后 AC 和 AD 连一条有向边,BC 和 BD …

二水中分白鹭洲

二水中分白鹭洲 题目大意 假设水中 \(n\) 条体积相等的鱼将按顺序依次排列,准备进行战斗。初始时,每条鱼可以选择向左游或向右游;但是鱼儿不太聪明,它们只会随机选择初始方向。 战斗时,若两条不同方向的鱼相遇,则体积大的鱼会吃掉体积小的鱼;如果两条鱼的体积相同,则向…