OOP第二次Blog

news/2025/1/19 23:11:51/文章来源:https://www.cnblogs.com/Luluhaha/p/18239159

前言

(1) 第四次题集的第一题已经经过了三次迭代,需要考虑到的情况越来越复杂,难度也越来越大,这让我感受到面向对象编程的基本原则的重要性,此前每一次迭代都应该谨慎,切忌为了偷懒就破坏类之间的关系(我第二次迭代就偷懒过了所有测试点,然后最后一次就狂改)。

(2) 第五次题集只有三道题,也是第一次迭代难度不大,但是进过前面几次大作业的磨练,我对类的使用明显愈发熟练,本次大作业用到了抽象类,我将电路设备定义为了抽象类,很轻松的AC这道题。

​ 然后是这题集的第三题,首次接触了集合类型,这道题是改错题,声明类型是Collection,实际类型是ArrayList,然后使用迭代器遍历所以员工,难度一般。

(3) 第六次题集只有一道题(看起来挺唬人),难度也没有很大,经过第一次迭代,加入了并联电路,电路设备也变多了,但是有一个关于精度的计算很难考虑到,花了很长时间调试。

第四次题集

设计与分析:

本次题集除了第三题其他都是很基础的题目,就分析一下最后一题,以下是类图:

本次大作业我设计的主要的几个类分别是

(1) 题目类(Question):用于保存一道题目的信息以及处理的方法。(与系列 1 相同,无变化)

private int num;// 题号

private String content, // 题目内容

standardAnswer;// 标准答案

boolean matchingStandardAnswers(String answer):判断是否符合标准答案

boolean isValid=true;//是否是有效的题目

void disabled() //当题目被删除,设置题目为失效状态

ArrayList answers //记录所有引用了该题目的答案

(2)试卷题目类(Question_Paper):用于保存试卷中的题目信息。由于试卷中的题目序号与题

目本身的题号不一致。且题目在不同试卷中的分值可能不一样,因此,设计试卷题目类。

int p_q_num;//试卷中题目的顺序号

Question question;//题目类的对象,保存题目信息

int question_score;// 题目分值

int judge_markAnswer(String answer) // 判断题目得分

(3)试卷类(TestPaper):保存和处理一张试卷的信息以及处理的方法,

int questionNum;// 题目数量

HashMap<String, Question_Paper> questions;//题目清单

void inputQuestion(int num, Question question):添加一道题目

void printQuestions():输出题目的内容~标准答案

boolean markQuestion(int num, String answer):判断第 num 题的正确性。

int sum-保存总分

int questionQuantity-保存题目数量

int getSum()****:获得总分

(4)答案类(Answer):用于保存答卷中一道答案的信息。

Question_Paper question;

String answer;

boolean mark;// 每一题的正确性

int score=0;// 每一题的得分

void calScore()//计算得分

void disable() //答案对应的题目失效,判分为 0

(5)答卷类(AnswerPaper):保存和处理一张答卷的信息以及处理的方法

TestPaper paper;//试卷信息

String[] answers;//每一题的答案信息boolean[] marks;//每一题的判题结果(对/错)

void printQ_A(int num):输出第 num 题的题目和答案(卷面答案,非标准答案)

boolean getJudge(int num):获得第 num 题的判题结果

void printJudges() :// 输出所有的得分以及总分,以空格分隔

String stuNum;// 学号

void** printErrorNumQuestion(Answer answer) // 输出试卷中错误题目号的题目

void** printInvalidQuestion(Answer answer)// 输出失效题目信息

(5)学生类(Student):保存学生的信息

String stuNum, stuName;

踩坑心得:

(1) 首先这次的大作业,我最后还有一个测试点没有过,现在我弄明白了,但是时间已经过了,这个题目的空白卷输入,就是只有一个卷子,没有题目序号,应该按正常的卷子输出,我的正则表达式有问题,没有捕捉到这种情况。

例如:

输入:#N:1 #Q:1+1= #A:2

T:1 1-5

X:20201103 Tom

S:1 20201103 #A:

end

应该将这种情况正常输出。

(2) 我这次又犯了上次同一个错误,正则表达式写错了,导致捕捉不准确。

public static boolean checkquestion(String str){String regstr="^#N:\\d*\\s*#Q:.*#A:.*";Pattern pattern= Pattern.compile(regstr);Matcher matcher=pattern.matcher(str);if(matcher.find()){return true;}else{return false;}}public static boolean checktest(String str){String regstr1="(\\d*)-(\\d*)";Pattern pattern1=Pattern.compile(regstr1);Matcher matcher1=pattern1.matcher(str);String regstr2="^#T:\\s*\\d+\\s*((\\d+\\s*-\\s*\\d+\\s*)+)$";Pattern pattern2=Pattern.compile(regstr2);Matcher matcher2=pattern2.matcher(str);if(matcher2.find()){return true;}else{return false;}}public static boolean checkstudent(String str){String regstr2="^#X:\\s*\\d+\\s(.*?)+(?:-\\d+\\s(.*?)+)*$";Pattern pattern1=Pattern.compile(regstr2);Matcher matcher1=pattern1.matcher(str);if(matcher1.find()){return true;}else{return false;}}

这几个check方法最后在同学的帮助下终于是改对了,下一次一定要仔细读取题目意思,谨慎考虑好之后在开始,不然写到一半出了问题很崩溃的。

改进建议:

这次写的大作业,还是出现前三次的问题,就是类之间的关系有些模糊不清,写到后面经常性用错,但是比起前几次的乱七八糟的代码,至少类的功能分的清楚了。

(1) 这次大作业如果将同学与答卷号码用HashMap保存起来,后续只需要通过迭代器就可以遍历所以答卷和学生,不用再像现在这样遍历所以答卷找同学,可以增强代码的可读性,而且代码也会更简洁,维护起来也容易。

(2) 试卷题目类也可以使用List泛型代替ArraysList存储试卷与题目的关系,这样可以直接使用Collections.sort方法进行排序。

第五次题集:

设计与分析:

​ 首先是这次题集的第一题,这是第一次出现,还没有进行迭代,特殊条件比较多难度一般,以下是类图:

这里主要设计了两个类:

(1) 电路设备类(Equipment):描述所有电路设备的公共特征。

abstract class Equipment {int switchstyle;//如果是开关 开关的状态public int getSwitchstyle() {return switchstyle;}public boolean IfPathway(){return false;}double voltage;//设备分到的电压public double getVoltage() {return voltage;}abstract public void setVoltage(double c);double resistor;//电阻abstract double getResistor();public double getContact1() {return contact1;}public void setContact1(double contact1) {this.contact1 = contact1;}String name;//设备名public String getName() {return name;}double contact1;//触脚1的电压public double getContact2() {return contact2;}public void setContact2(double contact2) {this.contact2 = contact2;}double contact2;//触脚2的电压abstract void display();//输出设备的状态abstract void close();}

(2) 串联电路类(Series):一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备。以下是部分代码:

class Series {public double getVoltage() {return voltage;}public void setVoltage(double voltage) {this.voltage = voltage;}private double voltage;public String getName() {return name;}public void setName(String name) {this.name = name;}private String name;public void VoltageDivision(){double aver=getVoltage()/getResistor();for(int i=0;i<list.size();i++){Equipment e= list.get(i);if(e instanceof Switch || e instanceof Governor || e instanceof ContinueGovernor)continue;else{e.setVoltage(aver*e.getResistor());}}}private double resistor;public double getResistor() {resistor = 0;for (int i = 0; i < list.size(); i++) {Equipment e = list.get(i);if (e instanceof Switch || e instanceof Governor || e instanceof ContinueGovernor)continue;elseresistor += e.getResistor();}return resistor;}
}

将设备类定义为抽象类,其余所有电器继承与设备类,然后使用串联电路类,然后将每个电路元件存入其中,
判断控制电器的状态,判断电路是否通路,模拟各种情况,最后输出各个元件的状态。

其中串联电路类内部使用ArrayList类型保存每一个设备,最后确定没一个开关的状态,最后进行排序输出即可。

然后是这次题集的第三道题,首次接触到了集合类型,这道题是一道改错题,使用Collection c = new ArrayList();
保存每一个员工,使用迭代器遍历输出,难度也一般。

//主函数
public class Main {public static void main(String[] args) {// 1、创建有序集合对象Collection <Employee>c  = new ArrayList();Scanner sc = new Scanner(System.in);// 创建3个员工元素对象for (int i = 0; i < 3; i++) {String employeeName = sc.nextLine();int employeeAge = sc.nextInt();sc.nextLine();Employee employee = new Employee(employeeName, employeeAge);c.add(employee);}// 2、创建迭代器遍历集合Iterator <Employee>it=c.iterator();//3、遍历while (it.hasNext()) {//4、集合中对象未知,向下转型Employee e = (Employee) it.next();System.out.println(e.getName() + "---" + e.getAge());}}

这是Main方法部分,声明了一个迭代器it,接收集合c的迭代器,然后遍历。

踩坑心得:

(1) 这次的大作业难度不大,但是由于看漏了条件,导致最后有几个测试点一直没有通过,这道题允许开关多次出现,最后输出结果要排序。后来我就声明了一个ArrayList类型专门保存所有开关,只有一遇见开关,就将这开关对象存入,判断是否有开关存在,如果有就排序输出。同时开关类也实现了Comparable接口。

@Overridepublic int compareTo(Switch o) {if (name.compareTo(o.getName()) < 0)return -1;elsereturn 1;}

(2) 还有本次大作业的分档变速器是必须在0-3之间,不能炒出这个范围的,需要加上特判条件。

例如:

 else if(Line.contains("#F")){if(Line.contains("+")&&gears<3){gears++;}else if(Line.contains("-")&&gears>0){gears--;}}

这样保证档位不会超出范围。

改进建议:

(1) 下一次迭代肯会将入并联电路,所以应将串联电路继承于电器设备类,这样方便下次迭代。

(2) 对于其他电路设备可以像对待开关一样操作,这次大作业说明了其余设备只出现一次,但是下次不一定,所以全部使用List泛型存储,在实现Comparable接口,方便排序。

以吊扇类为例:

 @Overridepublic int compareTo(Fan o) {if(name.compareTo(o.getName())<0)return -1;elsereturn 1;}if(D.size()!=0){Collections.sort(D);for(int i=0;i< D.size();i++)D.get(i).display();}

这样所有电路设备多次出现排序的问题就可以解决。

第六次题集:

设计与分析:

这次大作业比起上次大作业多了一个并联电路,将并联电路视为一种特殊的电路元件即可,但同时也需要主要并联电路的电阻和电压的计算涉及到精度问他。以下是新的类图:

这次主要的增加的新类:

(1) 并联电路类(Parallel):继承电路设备类,也看成是一个独立的类。

以下是主要属性和方法:

class Parallel extends Equipment {private ArrayList<Series> seriesList;Parallel(ArrayList<Series> seriesList) {this.seriesList = new ArrayList<>();this.seriesList = seriesList;}@Overridepublic void setVoltage(double c) {for(int i=0;i<seriesList.size();i++){Series series=seriesList.get(i);if(series.IfPathway()){series.setVoltage(c);series.VoltageDivision();}}}@Overridepublic boolean IfPathway()//检查并联是否通路{for(int i=0;i<seriesList.size();i++){if(seriesList.get(i).IfPathway()){return true;}}return false;}@Overridedouble getResistor() {for(int i=0;i<seriesList.size();i++){if(seriesList.get(i).Ifshort()){return 0;}}double r = 0;double R = 0;for (int i = 0; i < seriesList.size(); i++) {Series s = seriesList.get(i);if(s.IfPathway()){R += (1.0 / s.getResistor());}}r =  (1.0 / R);return r;}@Overridevoid display() {}@Overridevoid close() {}
}

并联电路也是一个特殊的电路设备,所以他也有名字,电阻,电压。需要注意的是并联的电阻计算和电压的计算会有精度问题。

题干中说明了并联电路所包含的串联电路会在其之前输入,所以只要将每一条路(出了连接电源的串联)存在一起,创建并联电路时一起加入就行。

踩坑心得:

(1 )这道题涉及到并联电路电阻的计算,那么就肯定会出现一些,无限循环小数等非常规小数,导致计算结果出错。

例如:

输入:

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

错误输出:

@K1:closed
@K2:closed
@L1:1.00
@D1:360
@D2:199
@D3:199

这是一个人标准错误的答案。

正确输出:

@K1:closed
@K2:closed
@L1:1.00
@D1:360
@D2:200
@D3:200

当D2的转速为199.99999时最后应输出200,而不是199。这是计算电压是,没有处理好。需要进行精度判断,如:

double TF=c1-Math.floor(c1);double TC=Math.ceil(c1)-c1;if(Math.min(TF,TC)<1e-10){c1=Math.round(c1);}

这需要每次计算电压时加上这个判断即可AC。

改进建议:

​ 下次迭代是可能会加入并联电路串联的情况,所以在加入并联电路时需要进行遍历所有此前的串联,找到符合的串联,再加入并联电路中。为了应对各种迭代情况,所以类之间的耦合性一定要设法降低,不能导致牵一发而动全身,这样修改代码的工作量太大了。

总结:

对面向对象编程(OOP)概念理解加深了,Java是一种面向对象的语言,通过这三次作业,更深入地理解类、对象等概念。

然后代码组织与结构的能力增强,编写大型Java程序需要良好的代码组织和结构。

逐渐熟练如何使用接口、类组织代码,以及如何使用注释来提高代码的可读性。

调试能力提高,调试是开发过程中不可或缺的一部分。学会如何使用调试工具和技巧来定位和修复代码中的错误。

还精通了许多类的使用例如LinkList,ArraysList,HashMap等等。

然后是一些建议:
对于模拟家用电器控制系统可以在并联电路中加入一些特殊的元件,如电阻器,变压器等等,这样更符合实际情况。

之后的PTA作用可以加入一些算法数据结构的知识,促进我们自学,这几次作用都没有什么算法知识。

可以加入更多关联实际的题目,增强对面向对象的理解。

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

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

相关文章

Vue CLI 4与项目构建实战指南

这篇文章介绍了如何使用Vue CLI优化项目构建配置,提高开发效率,涉及配置管理、项目部署策略、插件系统定制以及Webpack和TypeScript的深度集成技巧。title: Vue CLI 4与项目构建实战指南 date: 2024/6/9 updated: 2024/6/9 excerpt: 这篇文章介绍了如何使用Vue CLI优化项目构…

2024.6.6学习java算法

java--- 对象赋值: 新建类class person包含String name和int age两个属性 在main方法中new person xiaoming,name为"xiaoming",age为19。 new person tiedan,tiedan=xiaoming。 输出tiedan的属性得到"xiaoming,19" tiedan.name="tiedan" 输出…

函数递归调用栈process

ret2text n步过 s步进 EIP所指的位置即为当前程序运行的位置gdb的栈地址顺序上高下底 s起始地址与ebp为0x18-0x08=0x10=16*bA 整数打包为字节 shellcode 我们现在做的很多题目,都是堆栈不可执行,如果要使堆栈可执行,就要用到修改内存属性的函数,这属于比较高级的利用方式,…

pwntool类型转换

pwntools:类型转换 编码是什么?编码就是把一个字符用一个二进制来表示。 以ASCII编码为例,它规定1个字节8个比特位代表1个字符的编码,也就是"00000000"这么宽,一个一个字节的解读。例如:01000001表示大写字母A,有时我们会“偷懒"的用65这个十进制来表示A…

git-jenkins阶段01 DevOps介绍, 版本控制系统, Git的安装与应用(内容对比,历史记录,恢复,分支)

1.DevOps介绍铁三角 开发 测试 运维老板的想法 产品经理的构造 开发的代码实现 测试的功能测试 运维平台构建 代码的上线开发 测试 变化 代码的更新 运维 稳定 网站能够正常运行下去2. 版本控制系统vcs 记录文件的所有的历史变化 随时…

mysql阶段04 连接工具, 连接方式, 启动关闭mysql

一、mysql连接管理 1.连接工具 1)mysql自带的连接命令 mysql#常见用于连接的参数: -u: 指定用户 mysql -uroot -p: 指定密码 mysql -uroot -p123 -h: 指定连接的主机 mysql -uroot -p123 -h10.0.0.51 -P: 指定端口 mysql -uroot …

OOP4-6次作业

OOP4-6次作业 一.前言: 1.第四次PTA: ①题目理解: 延续前面的四次PTA,只不过在此基础上进行更全面的处理,新增了其他的一些点。例如增加了多选题,的输入方式,这样,也就增加了多选题的输出方式。增加了一些填空题,对其部分正确的判断变成了一个难点,也增加了其输出的难…

第4到6次PTA大作业课后分析与反思 BLOG

前言 第4到6次大作业分为两个部分,第4次大作业是对上三次大作业的最终迭代,第5到第6次是新的大作业,是关于电路的迭代。 设计与分析 第四次大作业题目: 设计实现答题程序,模拟一个小型的测试,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目…

ch2 信息与行为

信息与行为重点(from 裴雷)阿莱悖论(独立性) 冯诺依曼公式 贝叶斯信念 信息搜寻预期收益(大题)理性人 经济理性的两个基本假定是:自利性和极大化原则自利性:在行为选择中个体总是倾向选择对自身最具有优势的选择方案 极大化原则,也可以包括极小化原则,指个体对最大幸福…

关于第四到六次PTA作业总结

一.第四到六次PTA作业的分析 1.第四次PTA作业的分析 (1). 理解题目的需求 在编程之前,准确理解题目需求至关重要。本题中,输入格式和输出格式的细节非常多,包括各种异常情况的处理,这些都需要仔细阅读题目描述,确保理解了每一个细节。在实际操作中,我采取了以下措施: …