oop4~6次作业总结(第二次Blog)
oop4~6次作业总结(第二次Blog)
目录
一、前言
二、设计与分析
三、踩坑心得
四、改进建议
五、总结
一、前言
1、第四次作业
这三道题是对类设计的检测,后两题较基础,第一题在前两次作业的基础上增加了难度,增加了多选题、填空题和多试卷,如果前两次的类设计得比较合理的话,实现起来也不是很困难,主要还要考虑部分正确,但是在做这道题的时候发现了一个奇怪的点,有一个测试样例,我在eclipse和IDEA上测试的答案都是正确的,可是在PTA上运行又变成错误答案了🤔(这是为什么呢??)
2、第五次作业
第一题是智能家居强电电路模拟系统,受控设备和控制设备只考虑一种,只考虑串联电路,本次迭代比较简单;第二题考查集合接口的实例化、遍历方法和向下转型,检测对代码的调试,以及List的知识点;第三题是对迭代器使用的考察,比如:不能单独写 Iterator it; 使用Conllection需要创建。第五次作业总体来说都比较简单,需要掌握相关知识,第一题也需要注意细节,类设计最好与后续的迭代相结合。经过上一次的踩坑后,这次也运用了老师建议的类设计。
3、第六次作业
第六次作业只有一道题,与上次相比,增加了并联电路、控制设备和受控设备也可以有多个,这次最主要的问题是计算电阻、对电压的分配,以及各电器的输出顺序,刚开始看到只有三个测试样例,以为不会很难,没想到是我想多了,最后提交答案时要通过三十多个测试点,好多个测试点都不知道是什么原因,感觉像是在大海捞针。
二、设计与分析
1、第四次作业
类图:
因为多了多选题和填空题,所以将Question命名为他们的父类,AnswerPaper用来存放答卷信息(包括编号,学号,题目编号以及答题答案),Test用来存放试卷信息(包括编号,题目编号,题目分数),Question用来存放题目信息(题目编号,题目,标准答案),Question_Z是多选题,Question_K是填空题,Students用来存放学生信息(包括所有学生学号,所有学生姓名),DeleteInformation用来存放删除信息(包括删除的字符,删除的编号)。这次的类设计比上次好一点,但还是过于简单,类与类之间的联系较简单。
设计分析:
Main函数的分析图
可以看出Main的复杂度较高。因为Main函数中首先读取输入信息用了While循环,其中出现了冗杂的代码,比如:if语句本来就是While的最后一个条件,但是我还写了continue,可以省略。在Main函数中还运用了大量的if-else和for循环,对于一些不必要的代码可以省略删除。其他类复杂度相差不大。
2、第五次作业
类图:
第一题是智能家居强电电路模拟系统,Control用来存放控制设备,Switch是开关(可以有多个,其中包括了开关名、是否打开),Continuous是连续调速器(只能有一个,只有档位),Series是分档调速器(只能有一个,只有档位),其中Control是Switch、Continuous、Series的父类;Controlled用来存放受控设备,Lamp是灯(有亮度,Daylight是日光灯,Incandescent是白炽灯,两者都是Lamp的子类),Fan是吊扇(有风速),其中Controlled是Lamp、Fan的父类;Concatenation是串联电路;Main函数进行输入输出。
设计分析:
可看出虽然Main函数中的复杂度更高,但是也没有完全在Main里操作代码,相比前面几次作业好点了,复杂度高还是因为if-else语句较多
Main函数的分析图:
3、第六次作业
类图:
在上一次迭代的基础上新增了落地扇、并联、大串联、设置、输出类。并联类存储每一个M;大串联则为整个电路上的并联,加上总电路上的控制设备和受控设备;设置类是对初始设备电压的设置。
设计分析:
输出类的复杂度更高,因为运用了大量的for循环,感觉不仅复杂,还特别绕。
查看代码
public class OutPut {
public OutPut() {
}
public OutPut(ArrayList<Parallel> para, TotalConcatenation total) {
ArrayList<Control> controls = new ArrayList();
ArrayList<Controlled> controlleds = new ArrayList();
for (int i = 0; i < para.size(); i++) {
for (int k = 0; k < total.getParaName().size(); k++)
if (total.getParaName().get(k).equals(para.get(i).getName())) {
ArrayList<Concatenation> c = para.get(i).getConca();
for (int j = 0; j < c.size(); j++) {
for(int n=0;n<c.get(j).getControl().size();n++)
controls.add(c.get(j).getControl().get(n));
for(int m=0;m<c.get(j).getControlled().size();m++)
controlleds.add(c.get(j).getControlled().get(m));
}
}
}
for(int i=0;i<total.getControl().size();i++)
controls.add(total.getControl().get(i));
if (total.getControlled() != null)
for(int i=0;i<total.getControlled().size();i++)
controlleds.add(total.getControlled().get(i));
ArrayList<Switch> k = new ArrayList();
ArrayList<Series> f = new ArrayList();
ArrayList<Continuous> l = new ArrayList();
ArrayList<Incandescent> b = new ArrayList();
ArrayList<Daylight> r = new ArrayList();
ArrayList<Ceilingfan> d = new ArrayList();
ArrayList<Floorfan> a = new ArrayList();
for (int i = 0; i < controls.size(); i++) {
if (controls.get(i) != null) {
if (controls.get(i) instanceof Switch)
k.add((Switch) controls.get(i));
else if (controls.get(i) instanceof Series)
f.add((Series) controls.get(i));
else if (controls.get(i) instanceof Continuous)
l.add((Continuous) controls.get(i));
}
}
for (int i = 0; i < controlleds.size(); i++) {
if (controlleds.get(i) instanceof Incandescent)
b.add((Incandescent) controlleds.get(i));
else if (controlleds.get(i) instanceof Daylight)
r.add((Daylight) controlleds.get(i));
else if (controlleds.get(i) instanceof Ceilingfan)
d.add((Ceilingfan) controlleds.get(i));
else if (controlleds.get(i) instanceof Floorfan)
a.add((Floorfan) controlleds.get(i));
}
Collections.sort(k);
Collections.sort(f);
Collections.sort(l);
Collections.sort(b);
Collections.sort(r);
Collections.sort(d);
Collections.sort(a);
for (int i = 0; i < k.size(); i++)
k.get(i).show();
for (int i = 0; i < f.size(); i++)
f.get(i).show();
for (int i = 0; i < l.size(); i++)
l.get(i).show();
for (int i = 0; i < b.size(); i++)
b.get(i).show();
for (int i = 0; i < r.size(); i++)
r.get(i).show();
for (int i = 0; i < d.size(); i++)
d.get(i).show();
for (int i = 0; i < a.size(); i++)
a.get(i).show();
}
}
三、踩坑心得
1、第四次作业
发现PTA一个比较坑人的点,在PTA上的答案不对,但是在其他程序上运行就是对的。
题目踩的坑主要是多试卷、多学生并且是乱序出现时,有时候数组没注意到就会出现非零返回的情况;还有正则表达式,一点小小的错误也会造成这道题某个测点的错误;对答案判断正误时,答案信息少于试卷的题目数量或者是没有该题答案时是比较容易绕晕我的问题,所以if-else语句写得稍微有点多,这也会导致复杂度增加。
比如我的一个checkAnswer的方法:
查看代码
public void checkAnswer(LinkedList<Question> question, String num, String answer1) {
String answer = answer1.trim();
int flag = 0, i, count = 0;
for (i = 0; i < question.size(); i++) {
if (question.get(i).getNZK() == 0) {
if (question.get(i).getQuestionNum().equals(num)) {
if (question.get(i).getQuestion() == null) {
System.out.println("the question " + num + " invalid~0");
break;
} else if (answer.equals(question.get(i).getStandardAnswer())
&& question.get(i).getQuestion() != null) {
System.out.println(question.get(i).getQuestion() + "~" + answer + "~" + "true");
break;
} else {
System.out.println(question.get(i).getQuestion() + "~" + answer + "~" + "false");
break;
}
}
} else if (question.get(i).getNZK() == 1) {
LinkedList<String> standardAnswers = new LinkedList();
LinkedList<String> answers = new LinkedList();
String[] a = answer.split("\\s");
for (int m = 0; m < a.length; m++)
answers.add(a[m]);
String[] A = question.get(i).getStandardAnswer().split("\\s");
for (int m = 0; m < A.length; m++)
standardAnswers.add(A[m]);
if (question.get(i).getQuestionNum().equals(num)) {
if (question.get(i).getQuestion() == null) {
System.out.println("the question " + num + " invalid~0");
} else if (answers.size() == standardAnswers.size() && answers.size() == 0 && standardAnswers.size() == 0) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "true");
} else if (answers.size() == 0 || answers.size() > standardAnswers.size()) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
} else if (question.get(i).getStandardAnswer().contains(answers.get(0))
&& question.get(i).getQuestion() != null) {
for (int j = 0; j < answers.size(); j++) {
if (question.get(i).getStandardAnswer().contains(answers.get(j)))
count++;
else
flag = 1;
}
if (flag == 1) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
} else if (count != standardAnswers.size() && flag == 0) {
System.out
.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "partially correct");
} else if (count == standardAnswers.size() && flag == 0) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "true");
}
break;
} else {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
break;
}
}
} else if (question.get(i).getNZK() == 2) {
LinkedList<String> answers = new LinkedList();
LinkedList<String> standardAnswers = new LinkedList();
// Pattern pattern = Pattern.compile("([^:]*)(或)*(.*)");
if (answer.contains("或")) {
String[] a = answer.split("或");
for (int m = 0; m < a.length; m++)
answers.add(a[m]);
} else {
answers.add(answer);
}
if (question.get(i).getStandardAnswer().contains("或")) {
String[] a = question.get(i).getStandardAnswer().split("或");
for (int m = 0; m < a.length; m++)
standardAnswers.add(a[m]);
} else {
standardAnswers.add(question.get(i).getStandardAnswer());
}
if (question.get(i).getQuestionNum().equals(num)) {
if (question.get(i).getQuestion() == null) {
System.out.println("the question " + num + " invalid~0");
} else if (answers.size() == standardAnswers.size() && answers.size() == 0 && standardAnswers.size() == 0) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "true");
} else if (answers.size() == 0 || answers.size() > standardAnswers.size()) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
} else if (question.get(i).getStandardAnswer().contains(answers.get(0))
&& question.get(i).getQuestion() != null) {
for (int j = 0; j < answers.size(); j++) {
if (question.get(i).getStandardAnswer().contains(answers.get(j)))
count++;
else
flag = 1;
}
if (flag == 1) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
} else if (count != standardAnswers.size() && flag == 0) {
System.out
.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "partially correct");
} else if (count == standardAnswers.size() && flag == 0) {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "true");
}
break;
} else {
System.out.println(question.get(i).getQuestion() + "~" + answer1 + "~" + "false");
break;
}
}
}
}
}
我认为可以转换一下自己的思路,思考一下应该怎样写更加便捷并且不会把自己绕晕,过于冗长繁琐,写代码之前也应该斟酌一下,避免出现后面写了一大堆代码后发现想要修改很多地方的情况。上一部分不太清晰的地方即使改正,不然后续的迭代只会越来越错。
2、第五次作业
第五次作业后两题都是检测基础的调试改错,主要考察集合接口的实例化、遍历方法和向下转型、List、对迭代器的使用,但是也有可能被正确的代码所迷惑,其实主要还是知识点没有掌握的原因,对于这类知识,需要多看、多记、多写,这样才能更加巩固。第一题是智能家居强电电路模拟系统,自己的审题能力依旧欠缺,比如:题中所给开关可以为多个,而我就忽略了这句话,主观臆断认为开关只有一个;还有对于电路没有控制设备的情况,刚开始并没有考虑到,所以最后得出的结论都是0,因为类中信息默认为0;
踩坑时的测试点错误:
最后就是分档调速器的问题,题目中所给信息是最高三档,最低零档,我没有考虑到这个问题,甚至还会出现越界的情况,这是考虑不周的原因。这次给的正则相较于上次简单,但还是需要细心。
3、第六次作业
其实第六次作业最主要的踩坑点是没有第一时间开始写代码,因为其他任务的冲突,导致我缓了两天才开始看题目,这也给我自己减少了认真思考的时间。这次老师给出的测试样例比较多,需要自己慢慢调试,增加了并联电路,所以需要考虑的情况有很多,(可能是我物理不太好的原因吧)第一次提交就只有12分,把我吓了一跳,后面改了很久仍然只有12分,只好去求助同学,没想到是因为我没有考虑多个控制设备和多个受控设备,每个设备只有一种情况,所以导致问题比较多;还有就是排序的问题,绞劲脑汁想了很久,发现用CompareTo还是比较好写的,但是用的时候继承了Comparator的接口,导致多处报错,这也是知识点掌握不牢的问题。还有一点小粗心,比如在调用函数时会不小心把该调用的函数写成另一个不该调用的函数,粗心的错误是最好改的,希望后续在完成作业时能够更加细心,不要犯这种错误了。
题中并没有说只有一个设备,所以需要多种考虑。
四、改进建议
- 做题时需要认真审题,格式、要求、设计都要好好看。
- 在做题前需要边读题边思考,有一个清晰明确的思路后再开始编写,不然写了一大半发现思路错误后,只能推翻重写了,不仅浪费时间,还影响了自己的思路。
- 做题时不能主观臆断,要看清楚题目中所给出的正确信息,不能盲目猜想。
- 进行后续迭代时可以转换一下自己的思路,思考一下应该怎样写更加便捷并且不会把自己绕晕,过于冗长繁琐,写代码之前也应该斟酌一下,避免出现后面写了一大堆代码后发现想要修改很多地方的情况。上一部分不太清晰的地方即使改正,不然后续的迭代只会越来越错。
- 自己的时间要合理安排,应该是每科平衡,而不是目前哪科更急就只看哪科,在合适的时间做合适的事情。
- 下一次迭代可以在上一次的基础上重新编写一下串并联之间的关系,以及电压的设置,仔细思考更简单的方法,遵守单一职责原则,提高类的可读性,可维护性。
五、总结
经过这几次的PTA练习,我认为我自己在类的设计上进步了一点,但是仍然有很大的问题,所以平时还是得利用自己的时间,最好是在头脑较为清晰的时刻多敲敲代码,来加强对知识点的掌握,这样做事也会事半功倍。以后的设计会越来越复杂,更考验我们的知识掌握能力,这几次层层递进的练习也让我学会一些知识点:接口的实例化、遍历方法和向下转型,检测对代码的调试,以及List的使用、类的设计技巧:1. 保证数据私有;2. 对数据初始化;3、不要在类中使用过多的基本类型(用其他的类代替多个相关的基本类型的使用,这样会使类更加易于理解且易于修改。)4、将职责过多的类进行分解;5、类名和方法名要能够体现它们的职责。由于我做题时只想过测试点,完全忽略了类设计,所以对于我自己来说的话,类该如何设计是需要进一步学习和研究的,还有在测试的过程中,也要养成举一反三的好习惯。做题时注意审题,不要粗心,在做题前需要边读题边思考,有一个清晰明确的思路后再开始编写,不然写了一大半发现思路错误后,只能推翻重写了,不仅浪费时间,还影响了自己的思路。最后希望老师能多给一些测试样例,或者测试点写上对应的问题,不然一点点测试感觉像在大海捞针😭!