前言:前面3次作业相对来说比较简单,答题判题程序虽然又更新了,但是有以往的程序基础就比较简单了。这次就只是加上了几个多选选择题和多选填空题,就只要将正则表达式修改一下就可以了基本判断也是可以不用改变的。这次的家电强电电路模拟程序也是比较新颖,其中映入眼帘的就是它的题目要求,非常多。所以说在写代码前要先对于题目的整体结构给把握住,这样的话就可以起到事半功倍的效果了。整体来说,这次作业主要考察了正则表达式,结构处理和其他的方法,难度适中。
设计与分析:
1. 答题判题程序4:在第3次迭代的时候,本人的代码写的非常的烂,因此我直接重新开始写一遍。在以前的基础上,我直接将试卷的题目顺序在正则表达式中排好,因此可以减去在答卷时过于麻烦的比对答案对应的题目好。
public void set(int ExamQuestionNumber,int QuestionNumber,int Question,int grade) {
this.ExamQuestionNumber = ExamQuestionNumber;//第几章卷子
this.QuestionNumber = QuestionNumber;//第几到题(第一题,第二题)
this.Question = Question;//第几到题对应的第几个问题
this.grade = grade;//分数}
在正则表达式切除时这个QuestionNumber
就对应的是这张试卷对应的题目的题号。if(nonumber==answerSheets.get(j).QuestionNumber)
在学生输入答卷信息时就可以来比较这个题号是否对应了,也就少去了遍历寻找题号的问题了。这次迭代多了多选选择题和多选填空题。所以说,我直接在试卷对应的答案改成了一个字符数组,可以添加多个答案。同时在正则表达式的截取要更加“小心”了。以多选填空题为例
String regex = "#K:\\s*([1-9]\\d*)\\s*#Q:(.*)#A:(.*)";//把试卷题目号提取出来
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
MultipleChoiceFillInQuestion ans = new MultipleChoiceFillInQuestion();
if (matcher.find()) {
String[] parts = matcher.group(3).trim().split("或"); // 使用空格分割字符串
ans.answer = new String [50];
for(int i=0;i< parts.length;i++)
{ ans.answer[i] = parts[i]; }
ans.set(Integer.parseInt(matcher.group(1).trim()),matcher.group(2).trim(),true);
return ans;
这样就可以单纯的把全部答案给截取出来了。但是要注意,因为答案是一个数组,因此在单选题是,就只要一个答案,所以说在答卷对应是要进行判断是否为多选题。
整个代码的结果也是这个样子。
全局结果为:
- 整题的思路就是先把每一张试卷的问题给列举出来,然后再对于学生提交的答案卷的数据,先找到他的题目,再找到对应的答案是否满足就可以了,把对应的分数记录起来,最后再输出就行了。
2.家电强电电路模拟程序-1:因为这次只是初次迭代因此难度不是非常大。也许最难的是从一大串文字中截取信息吧。题目要求的内容实在是太多了。这次的电路还是很简单的就只有一个电器,同时电阻也不用考虑,就只要单纯的写出电阻类就好了。并且通过发现这次输入的数据可以只截取空格前面的或者后面的,对于引脚并没有什么太大的作用。同时这次我采用在main函数中添加非常多的ArrayList且是static类型。可以让这些数据在全局中都可运用。使电器可以全局使用。
因此全局的结构为:
- 整题的思路其实就是把这一条路上的开关,电器等等东西记录起来,先来判断电压就可以了,因为就只有一个电器所以说这个总电压就是这个电器的电压。总的来说不需要考虑什么东西。
3.家电强电电路模拟程序-2:在上一次的迭代中,整体来说难道增强了。我的上一次的好多情况都用不到,修改了好多。其中最大的变化就是串联电路类的增加以及加上了电阻的考虑。在这个类中我加上了前面的全部电器,开关,调速器,以及并联电路全部类。因此加上了ArrayList,将这些类联系起来。
`
ArrayList
ArrayList<FluorescentLamp> fluorescentLamps = new ArrayList<>();
ArrayList<CeilingFan> ceilingFans = new ArrayList<>();
ArrayList<FloorFan> floorFans = new ArrayList<>();
ArrayList<ParallelConnection> parallelConnections = new ArrayList<>();
ArrayList<Switch> switches = new ArrayList<>();
ArrayList<DifferentialGovernor> differentialGovernors = new ArrayList<>();
ArrayList<ContinuousGovernor> continuousGovernors = new ArrayList<>();`
ArrayList确实非常的好用。在串联电路的处理数据之后,直接add添加即可。同时在这次迭代中可能会出现并联电路中其中一条串联电路出现了短路现象。就会直接影响次串联中电路的电器电压和对应并联电路的总电阻。因此我在串联电路类中定义了是否开关的属性
boolean on = true;//是否开着的在经过一下判断
再经过以下判断串联电路是否短路
int flag = 0;
for (int i = 0; i < seriesConnections.size(); i++)//对串联电路进行遍历
{ flag = 1;
if (seriesConnections.get(i).switches.size() == 0)//如果是串联电路没有开关的话
seriesConnections.get(i).on = true;
else {
for (int j = 0; j < seriesConnections.get(i).switches.size(); j++)//对这条串联电路的开关进行遍历
{ if (seriesConnections.get(i).switches.get(j).SwitchingState != 1) flag = 0; }
if (flag == 1) seriesConnections.get(i).on = true;
else seriesConnections.get(i).on = false; }
}
不仅如此还加上了电阻,因此在每个类中都要加上类对应的电阻(除了调速器和开关不用),然后呢用分压的方式(分电阻除以总电阻再乘以电压)就可来计算分电压了。
以下就是我的全局结果:
-
整题解题思路就只要先找出主干路的每个电器(并联也可以算作一个电器)对应的电压。然后再把对应的电压就可以判断对应电器的亮度(旋转速度),其中对于并联的话就可以继续判断每个串联对应的的电压,之后再由每一个串联对应的电压再一次计算电器对应的电压。因此要得出对应的电阻非常的重要。这也是题目的难点了。
踩坑心得: -
- 并联电路的电阻计算出现错误:
起初我计算电阻是这样计算的:
public void consult()//得到并联的总电阻
{
double sum = 0;
for (int i = 0; i < seriesConnections.size(); i++) {
sum += 1.0 / seriesConnections.get(i).resistance;
}
this.resistance = 1.0 / sum;
}
中间没有if (seriesConnections.get(i).on)
这个判断,也就是没有考虑到如果是并联电路中的串联短路的情况,那么久会出现多算电阻的情况,导致并联电阻出错。因此我就在for循环加入了判断,也就可以刚好避免了这个问题。
public void consult()//得到并联的总电阻
{
double sum = 0;
for (int i = 0; i < seriesConnections.size(); i++) {
if (seriesConnections.get(i).on)
sum += 1.0 / seriesConnections.get(i).resistance;
}
this.resistance = 1.0 / sum;
}
不仅如此还有一个问题:当开关输入在并联电路之后就会导致并联电路的电阻算上了短路串联电路的电阻(按理说是要先把串联电路是否短路先进行判断的,然后再进行并联电路的电阻计算)因此我的解决方法是:在输入了end之后再进行串联电路短路的判断,之后才开始并联电阻的计算。这样就可以正确的计算出并联的电路电阻了。
- 并联电路的电阻计算出现错误:
-
2.总电压计算错误:
起初我的总电压是这样计算的:
double voltage = 0;
for (int i = 0; i < seriesConnections.size(); i++) {
if (seriesConnections.get(i).main)//找到了主支路
{
Resistance = seriesConnections.get(i).resistance;
if (seriesConnections.get(i).continuousGovernors.size() > 0)
voltage = 220.0 * seriesConnections.get(i).continuousGovernors.get(0).gear;
if (seriesConnections.get(i).differentialGovernors.size() > 0)
voltage = 220.0 *seriesConnections.get(i).differentialGovernors.get(0).output();
SeriesConnectionVoltage(seriesConnections.get(i), voltage);
}
}
这样经过判断是否有调速器再进行计算对应的总电压,但是呢会出现一个问题:就是如果是电路中没有调速器的话,它的总电压就是0了,那么之后的计算结果都是没有用的。因此应该在开头就要有电压的赋值
double voltage = 220;
这样如果是没有调速器也可以达到输出电压不为0的情况了。 -
3.错误格式输入问题:
在答题判题程序中,出现了错误格式输出错误的问题。经过多次查看发现就是因为在没有答案输入时,输出应该是answer is null
,但是我后续就没有了。导致这个输入答案的错误成绩应该是0,我就给使之没有了成绩。因此我加上了fen[fennumber] = 0;
fensum = fensum + fen[fennumber];
fennumber++;
这样就可以记录这个成绩了。
改进建议:我的答题判题系统的代码仍然需要修改:
- 1.main函数仍然用了非常多的定义类型,而且也写的很冗杂,没有过多的运用方法来简便代码。
- 2.并且在for循环时也没有去增强,比如说
for (int i = 0; i < differentialGovernors.size(); i++)
应该写成for (DifferentialGovernor governor : differentialGovernors)
这样会更好。 - 3.还有在判断ArrayList是否为空时是这样来判断的
if (seriesConnections.get(i).switches.size() == 0)
应该改为if (seriesConnections.get(i).switches.isEmpty())
这样也会增加代码的可读性。
我的家电强电电路模拟程序也是有大问题: - 1.过分运用ArrayList,使main中非常多的ArrayList,导致我的代码十分糟糕。
- 2.可修改性较差,代码中很多都是按照题目而写,比如说这次就只有AVV,那么我就只给出了220,根本就没有对电压的数值进行判断。
- 3.没有对对应的方法写注释,导致在后续的迭代中看不明白我的方法作用。
总结:经过了这三次作业的学习,本人的代码能力也取得了一定的提升。以前的我习惯乱命名(比如说是a,b,c这种命名习惯)导致我在一段时间之后再看该代码就已经看不明白了,对本人理解代码取到了非常大的阻碍。如今我也会运用驼峰式命名法(比如SwitchingState
,代表了开关状态;SeriesConnection
代表串联电流以及等等)。起初我在代码中会更加运用方法来进行,可以使我的main函数非常的简洁,方便观看。比如家电强电电路模拟系统这一例子。
也在后来为迭代打下了基础,给出了一个整体框架,有利于接下来迭代。
- 同时也需要在以下方面进一步学习和研究
(1)多学习算法,可以提高算法的利用效率,不会讲代码写的冗杂。
(2)多加了解其他类并且能够熟练掌握它,以便在后续的学习生涯中可以将代码写的更好,时间利用率更高。
以下是我的建议: - 相关建议:
希望在给出的PTA及实验的题目中尽量将问题描述的更清楚一些,以便更好的理解出题人的意思,以便写出更好的代码。