- PTA训练集总结blog
- 1.前言
- 2.设计与分析
- 题目集七 7.1家居强电电路模拟系统—3
- 关于设计要求:
- UML类图及设计分析:
- 部分源码:
- 复杂度分析:
- 题目集八 7.1 家具强电电路模拟系统—8
- 关于设计要求:
- 部分源码:
- 复杂度分析:
- 题目集七 7.1家居强电电路模拟系统—3
- 3.踩坑心得
- 4.改进建议
- 5.总结
PTA训练集总结blog
1.前言
1.这次是7-8次的pta作业的一个总结性blog,依旧是熟悉的家居强电电路模拟系统,在前面的基础上又衍出第三代和第四代。很遗憾的是这两次的作业我都没有能通过全部测试点,但也是学到了很多东西。前言无力,请移步正文。
2.设计与分析
题目集七 7.1家居强电电路模拟系统—3
关于设计要求:
1、控制设备
本题模拟的控制设备包括:开关、分档调速器、连续调速器、互斥开关。
为避免短路,互斥开关设置了限流电阻,12引脚之间默认电阻为5,13引脚之间默认电阻为10。
2、受控设备
本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
本次迭代模拟一种受控窗帘:
受控窗帘的电路符号为S,其最低工作电压为50V,电压达到或超过50V,窗帘即可正常工作,不考虑室外光照强度和室内空间大小等因素,窗帘受室内灯光的光照强度控制。
受控设备电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20,窗帘电阻为15。
UML类图及设计分析:
emm…类图还是较复杂的,在这次我换了一种结构来写这道题,毕竟我之前的结构已经不适合再迭代了,我也是吃了没设计好的亏,吃一堑长一智了也是。这道题我设计了一个parseinput去处理读取和连接串并联的功能,具体的电压赋值用的是电流 写在了串联电路类中。互斥开关是用的两个小开关的结构,避免了引脚识别输入输出电势,这在下一次的迭代中给我留下了一个天大的坑。仓促设计的结构,除了这个暗坑,还有好多没有注意到的点。
部分源码:
class SeriesElectric extends Electric{//private double I;private final ArrayList<Electric> elements = new ArrayList<>();public SeriesElectric(){}public ArrayList<Electric> getElements() {return elements;}public void addElement(Electric electric){int f=0;for(Electric e:elements){if(e instanceof ElectricEquip&&electric instanceof ElectricEquip){if(((ElectricEquip) e).type.equals(((ElectricEquip) electric).type)&& ((ElectricEquip) e).num.equals(((ElectricEquip) electric).num)) {f=1;}}else if(e instanceof SeriesElectric&&electric instanceof SeriesElectric){if(e==electric){f=1;}}else if(e instanceof ParallelElectric&&electric instanceof ParallelElectric){if(e==electric){f=1;}}}if(f==0)elements.add(electric);}@Overridepublic void generateResistance() {for(Electric element : elements) {if(element instanceof K) {if(!((K) element).num.equals("one") && !((K) element).num.equals("two")){continue;}}if(element.resistance == 0){if(element instanceof ParallelElectric) element.generateResistance();else if(element instanceof SeriesElectric) element.generateResistance();}resistance += element.resistance;}}public void setElectric(){double I = voltage / resistance;for(Electric element: elements){if(element instanceof L){L l = (L) element;voltage = l.getOutput(voltage);I = voltage / resistance;}else if(element instanceof F){F f = (F) element;voltage = f.getOutput(voltage);I = voltage / resistance;}else if(element instanceof LightB) {LightB b = (LightB) element;b.setVoltage(I * b.resistance);b.calV(I);b.setPower();}else if(element instanceof LightR){LightR r = (LightR) element;r.setVoltage(I * r.resistance);r.calV(I);r.setPower();}else if(element instanceof Fan){Fan f = (Fan) element;f.setVoltage(I * f.resistance);f.calV(I);f.setPower();}else if(element instanceof gFan){gFan a = (gFan) element;a.setVoltage(I * a.resistance);a.calV(I);a.setPower();}else if(element instanceof S){S a = (S) element;a.setVoltage(I * a.resistance);a.calV(I);//a.setPower();}else if(element instanceof SeriesElectric){SeriesElectric se = (SeriesElectric) element;se.setVoltage(I * se.resistance);se.calV(I);se.setElectric();}else if(element instanceof ParallelElectric){ParallelElectric p = (ParallelElectric) element;p.setVoltage(I * p.resistance);p.calV(I);p.setElectric();}//System.out.println("I:" + I + " V:" + voltage);}}public boolean connect(){for(Electric electric: elements){if(electric instanceof ElectricEquip){ElectricEquip e = (ElectricEquip) electric;if(e.getType().equals("K")){K k=(K) e;if(!k.getState()) return false;}if(e.getType().equals("H")){H h=(H) e;String []a=e.num.split("-");if(!h.getState(a[1])) return false;}}else if(electric instanceof ParallelElectric){ParallelElectric e = (ParallelElectric) electric;if(!e.connect()) return false;}else if(electric instanceof SeriesElectric){SeriesElectric se = (SeriesElectric) electric;if(!se.connect()) return false;}}return true;}
}
复杂度分析:
Method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Electric | 1.11 | 2.0 | 10.0 | |
ElectricEquip | 1.0 | 1.0 | 8.0 | |
F | 1.83 | 4.0 | 11.0 | |
Fan | 1.5 | 3.0 | 6.0 | |
gFan | 2.34 | 5.0 | 7.0 | |
H | 1.5 | 2.0 | 9.0 | |
K | 1.5 | 2.0 | 9.0 | |
L | 1.0 | 1.0 | 5.0 | |
LightB | 1.5 | 3.0 | 6.0 | |
LightR | 1.25 | 2.0 | 5.0 | |
Main | 13.0 | 13.0 | 13.0 | |
ParallelElectric | 2.4 | 4.0 | 12.0 | |
ParseInput | 10.6 | 25.0 | 53.0 | |
S | 3.33 | 8.0 | 10.0 | |
SeriesElectric | 6.67 | 11.0 | 40.0 | |
Total | 204.0 | |||
Average | 2.72 | 5.73 | 13.6 |
题目集八 7.1 家具强电电路模拟系统—8
关于设计要求:
1、控制设备模拟
本题模拟的控制设备包括:开关、分档调速器、连续调速器、互斥开关。
2、受控设备模拟
为避免短路,互斥开关设置了限流电阻,12引脚之间默认电阻为5,13引脚之间默认电阻为10。
2、受控设备
本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
本次迭代模拟一种受控窗帘:
受控窗帘的电路符号为S,其最低工作电压为50V,电压达到或超过50V,窗帘即可正常工作,不考虑室外光照强度和室内空间大小等因素,窗帘受室内灯光的光照强度控制。
受控设备电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20,窗帘电阻为15。
本题不考虑输入电压或电压差超过220V的情况。
在本题中,并联电路M中的串联电路可以包含别的并联电路。
本系列题目中元件的管脚除了互斥开关的1引脚,其他所有引脚在电路中最多只出现一次。
增加管脚电压的显示
在输出每个电器的状态信息后,再依次输出该电器每个管脚的电压。(格式详见输出信息部分)
2)电流限制
电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”,与前面的信息之间用英文空格分隔。
例如:@B1:190 68-17 exceeding current limit error
本题各类电器的最大限定电流如下:
开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。
3)短路检测
如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”
4)并联电路中包含并联
本次迭代考虑并联电路中包含并联电路的情况,即构成并联电路的串联电路可以包含别的并联电路。
5)二极管
增加二极管元件,其电路特性为:正向导通,反向截止;其电器符号如图4所示,当电流从左至右流过时,二极管导通”conduction”,电阻为0;电流从右至左流动时,二极管截止”cutoff”,电阻无穷大,相当于开关打开。
二极管的标识符为’P’,左侧管脚编号为1,右侧管脚编号为2。
二极管如果两端电压相等,没有电流流过,分以下两种情况输出:
1、如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之为截止。
2、如果两端电压不为0,二极管导通。
这次的题目集说实话挺难,多了二极管,还要考虑并联套并联的情况了,还是把电压计算放在了SeriesElectric类的setElectric方法里,但是由于一开始就没有考虑引脚问题,所以到了最后一次迭代,做起来十分吃力,也是成功的没过很多测试点(尴尬脸)。
部分源码:
class ParseInput {public static void parseInput(ArrayList<String> input) {for(String s : input) {if(s.contains("#T")) parseSeriesElectric(s);else if(s.contains("#M")) parseParallelElectric(s);}for(String s : input) parseOperate(s);}private static void parseSeriesElectric(String i) {Pattern p = Pattern.compile("#T(\\d+)");Matcher m = p.matcher(i);SeriesElectric s = new SeriesElectric();if(m.find()) {String num = m.group(1);Main.series.put(num, s);}p = Pattern.compile("\\[ *(\\S+) +(\\S+)]");m = p.matcher(i);String str1 = "",str2 = "";while(m.find()){str1 = m.group(1);str2 = m.group(2);if(str1.equals("VCC")) {Main.electric = s;continue;}Pattern p1 = Pattern.compile("(\\w)(\\d+)-(\\S+)");Matcher m1 = p1.matcher(str1);if(m1.find()) {String type = m1.group(1);String num = m1.group(2);String feet = m1.group(3);//System.out.println(type + num);Electric e = getElectric(type, num, feet);if(e != null) s.addElement(e);}Matcher m2 = p1.matcher(str2);if(m2.find()) {String type = m2.group(1);String num = m2.group(2);String feet = m2.group(3);//System.out.println(type + num);Electric e = getElectric(type, num, feet);if(e != null) s.addElement(e);}}}private static void parseParallelElectric(String i) {Pattern p = Pattern.compile("#M(\\d+)");Matcher m = p.matcher(i);String num=null;ParallelElectric s = new ParallelElectric();if(m.find()) {num = m.group(1);Main.parallel.put(num, s);}p = Pattern.compile("M(\\d+)");m = p.matcher(i);while(m.find()&& !num.equals(m.group(1))){num = m.group(1);//System.out.println(num);ParallelElectric parallel = Main.parallel.get(num);s.addElement(parallel);}p = Pattern.compile("T(\\d+)");m = p.matcher(i);while(m.find()){num = m.group(1);//System.out.println(num);SeriesElectric series = Main.series.get(num);s.addElement(series);}}private static Electric getElectric(String type, String num,String feet) {Electric electricEquip = null;switch (type) {case "K" : {electricEquip = new K(num);if(!Main.Ks.containsKey(num)) {Main.Ks.put(num, (K) electricEquip);}}break;case "H" : {if(Integer.parseInt(feet)!=1){H ex = new H(num);;//1if(Main.Hs.containsKey(num)) {ex=Main.Hs.get(num);} else {Main.Hs.put(num, ex);}if(Integer.parseInt(feet)==2){electricEquip= ex.getK1();} else if (Integer.parseInt(feet)==3) {electricEquip= ex.getK2();}}}break;case "F" : {electricEquip = new F(num);if(!Main.Fs.containsKey(num)) {Main.Fs.put(num, (F) electricEquip);}}break;case "L" : {electricEquip = new L(num);if(!Main.Ls.containsKey(num)) {Main.Ls.put(num, (L) electricEquip);}}break;case "B" : {electricEquip = new LightB(num);if(!Main.Bs.containsKey(num)) {Main.Bs.put(num, (LightB) electricEquip);}}break;case "R" : {electricEquip = new LightR(num);if(!Main.Rs.containsKey(num)) {Main.Rs.put(num, (LightR) electricEquip);}}break;case "D" : {electricEquip = new Fan(num);if(!Main.Ds.containsKey(num)) {Main.Ds.put(num, (Fan) electricEquip);}}break;case "A" : {electricEquip = new gFan(num);if(!Main.As.containsKey(num)) {Main.As.put(num, (gFan) electricEquip);}}break;case "S" : {electricEquip = new S(num);if(!Main.Ss.containsKey(num)) {Main.Ss.put(num, (S) electricEquip);}}break;case "P" : {P ex = new P(num);;//1if(!Main.Ps.containsKey(num)) {Main.Ps.put(num, ex);if(Integer.parseInt(feet)==1){electricEquip=ex.getK1();Main.PKs.put(num,ex.getK1());}if(Integer.parseInt(feet)==2){electricEquip=ex.getK2();Main.PKs.put(num,ex.getK2());}}
// else {
// ex=Main
// }}break;case "M" : electricEquip = Main.parallel.get(num);break;case "T" : electricEquip = Main.series.get(num);break;}return electricEquip;}private static void parseOperate(String input) {Pattern p = Pattern.compile("#(\\w)(\\d+):*(\\S*)");Matcher m = p.matcher(input);if(m.find()){String type = m.group(1);String num = m.group(2);String op = m.group(3);switch (type) {case "K" : {if(Main.Ks.containsKey(num)){Main.Ks.get(num).toSwitch();}}break;case "H" : {if(Main.Hs.containsKey(num)){Main.Hs.get(num).toSwitch();}}break;case "F" : {if(Main.Fs.containsKey(num)){F e = Main.Fs.get(num);if (op.equals("+")) e.UpPos();else if (op.equals("-")) e.DownPos();}}break;case "L" : {if(Main.Ls.containsKey(num)){L e = Main.Ls.get(num);double parameter = Double.parseDouble(op);e.setParameter(parameter);}}break;}}}
}
class P extends ElectricEquip{private int state;public K getK1() {return k1;}private K k1;public K getK2() {return k2;}private K k2;public P(String num){super("P", num);k1=new K("first");k2=new K("second");k1.Imax=8;k2.Imax=8;k1.setState(1);k2.setState(0);resistance=k1.resistance;}public String judgeImax(){if((voltage/resistance)>Imax){return " exceeding current limit error";}return "";}@Overridepublic void print() {if(Main.PKs.containsKey(this.num)){K k=Main.PKs.get(num);if(k.getState()){System.out.println("@" + type + num + ":conduction" + " " + (int)k.input + "-" + (int)k.output +k.judgeImax());}else System.out.println("@" + type + num + ":cutoff" + " " + (int)k.input + "-" + (int)k.output +k.judgeImax());}}
}
复杂度分析:
Method | ||||
---|---|---|---|---|
Electric | 1.11 | 2.0 | 10.0 | |
ElectricEquip | 1.0 | 1.0 | 10.0 | |
F | 2.0 | 4.0 | 12.0 | |
Fan | 1.6 | 3.0 | 8.0 | |
gFan | 2.25 | 5.0 | 9.0 | |
H | 1.5 | 2.0 | 9.0 | |
K | 1.57 | 2.0 | 11.0 | |
L | 1.2 | 2.0 | 6.0 | |
LightB | 1.6 | 3.0 | 8.0 | |
LightR | 1.4 | 2.0 | 7.0 | |
Main | 14.0 | 14.0 | 14.0 | |
P | 1.6 | 3.0 | 8.0 | |
ParallelElectric | 3.16 | 7.0 | 19.0 | |
ParseInput | 11.4 | 28.0 | 57.0 | |
S | 2.6 | 8.0 | 13.0 | |
SeriesElectric | 9.33 | 23.0 | 56.0 | |
Total | 257.0 | |||
Average | 2.85 | 6.8125 | 16.0625 |
3.踩坑心得
关于电路-3:
1.关于互斥开关,刚开始我是没有考虑反接的情况的,后来卡在反接的设计上好久。因为我在读取的时候是没有去读【】里 “ - ”的后半段的,我不得不重新构写读取部分,倒也是让我写出来了,但是这种设计失误也是给了我狠狠的教训。
2.第二个就是输出问题,需要按照一定的顺序
关于电路-4:
1.二极管的设计在写了好几种之后我仿照互斥开关在类的内部写了两个开关属性,一个常开一个常闭。
2.还有就是输入输出电势的输出,真的的难倒我了,尤其我的互斥开关的存储方法导致我的互斥开关电势输出不能按照引脚编号。所以说互斥开关存储的时候一定要与引脚有所关联。
4.改进建议
在对字符串进行操作时,对于频繁的字符串操作,应该使用StringBuilder
或StringBuffer
类来提高效率。
对于代码异常情况,使用try-catch
语句块来捕获和处理异常,以保证程序的稳定性和可靠性。
通过设计分压方法将每个电路设备的输入输出电势赋值。
通过继承,多态进一步完善判定逻辑。如多个并,串联复合电路。
5.总结
通过本阶段的两 次题目集的练习,
- 数据结构:我更加熟悉了使用
List
和Map
等数据结构来处理和存储数据。这些数据结构在不同的情境下具有不同的优势,需要根据实际需求选择适当的数据结构。 - 循环和条件语句:更熟悉了使用增强
for
循环和if-else
条件语句来实现程序的控制流程,包括遍历数据、判断条件和执行不同的操作。 - 字符串处理:更熟练使用正则表达式,字符串操作的方法,如分割、替换和拼接字符串,以及比较字符串和提取子字符串。
- 熟练了抽象类的基本应用。
需要进一步学习和研究的地方包括:
- 异常处理:在给定的代码示例中,并未完全处理输入错误或无效数据的情况。学习处理异常,以提高程序的健壮性。
- 更多的数据结构和算法:除了示例中涉及到的数据结构,还有许多其他的数据结构和算法可供学习和探索。了解不同的数据结构和算法可以帮助我更高效地解决问题。
- 面向对象编程原则:学习如何设计良好的类和对象,并遵循面向对象编程的原则。这将使代码更加可维护、可扩展和可重用。
- 学会用设计迭代器等遍历和操作数据结构的工具来访问和操作数据结构。
总体而言,我已经掌握了更多Java编程的基础知识和技巧,但仍有许多内容需要进一步学习和研究。通过不断练习、听讲,阅读文章和参考优秀的代码示例,我相信可以不断提升自己的编程能力和解决问题的能力。