目录:
一)前言
二)设计与分析
三)踩坑心得
四)改进建议
五)总结
一.前言
(1)答题判题程序-4:
【1】知识点:正则表达式,判题的逻辑思维能力,数据形式转换。
【2】题量:很大
【3】难度:很难
是前三次答题判题程序迭代优化的最终形态,难度较高,它对于类的种类的个数已经类与类之间的关系的理解要求更要,同时需要考虑的方面也更多,程序的完善需要大量的时间。
(2)家居强电电路模拟程序-1:
【1】知识点:ArrayList的运用,物理知识的运用。
【2】题量:中等
【3】难度:较易
是家居强电电路模拟程序的基础,整体不难,但需要有一定的物理知识。
(3)家居强电电路模拟程序-2:
【1】知识点:对象类型转换,继承与多态,物理知识的运用。
【2】题量:较多
【3】难度:中等
是家居强电电路模拟程序的升级,虽然整体不难,但是代码的量较大,而且需要的物理知识相较家居强电电路模拟程序-1更多,但是也更加有趣。
二.设计与分析
答题判题程序-4:
(1)类的设计思路图:
(2)设计具体思路:
1.字符串录入:先创建一个String类的数组,用于储存输入的所有字符串,直到输入的字符串为"end"为止。以这个String类数组中的字符串为基础,进行处理。
2.对象的创建:各创建一条Test类(试卷)、Question类(题目)、Sheet类(答卷)、Student类(学生)的字符串,用于实现一个多个学生可有多个答卷回答多个写有多个题目的试卷,并创建一个整形数据question_num,并赋值为0,用于后面统计题目的个数。
3.各类对象的实例化:根据charAt(1)(字符串第二个字符)对步骤1中所实例化的字符串数组进行分类操作:
【1】charAt(1)为'N':则该字符串用于添加一个Question类对象并添加到Question类的ArrayList中,运用正则表达式"#N:\s\d+\s#Q:.\s#A:."对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,则利用截取出的三个字符串分别用于实例化int question_num、String question、String standardanswer。将这三个数据用于添加Question类的ArrayList的新Array(Question类),并将question_num加一。
【2】charAt(1)为'Z':则该字符串用于添加一个Choice_Question类对象并添加到Question类的ArrayList中,运用正则表达式"#Z:\s\d+\s#Q:.\s#A:."对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,先用上创建并实例化int question_num、String question,再根据截取到的第三个字符串,用substring(information[i].indexOf("#A:")+3).trim().split(" "),来创建并实例化一个String standardanswer[]数组,并统计其数量。将这四个数据用于添加Question类的ArrayList的新Array(Choice_Question类),并将question_num加一。
【3】charAt(1)为'K':则该字符串用于添加一个Fill_Question类对象并添加到Question类的ArrayList中,运用正则表达式"#K:\s\d+\s#Q:.\s#A:."对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,先如上创建并实例化int question_num、String question,再根据截取到的第三个字符串,用substring(information[i].indexOf("#A:")+3).trim().split("或"),来创建并实例化一个String standardanswer[]数组,并统计其数量。将这四个数据用于添加Question类的ArrayList的新Array(Fill_Question类),并将question_num加一。
【4】charAt(1)为'T':则该字符串用于添加一个Test类对象并添加到Test类的ArrayList中,运用正则表达式"#T:\s(\d)\s(\s\d+-\d+\s)"对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,先如上创建并实例化int test_num,再用split("-"),实例化int score_num[]、和int
score[],并根据"-",统计the_question_number(题目数)将这四个数据用于添加Test类的ArrayList的新Array。
【5】charAt(1)为'X':则该字符串用于添加一个Student类对象并添加到Student类的ArrayList中,运用正则表达式"#X:\s(\d+)\s(.)(-(\d+)\s(.))"对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,用split("-"),实例化String id、和String name将这两个数据用于添加Student类的ArrayList的新Array(注:该操作一条字符串可以提取到多个学生的id和name,是进行了循环操作)。
【6】charAt(1)为'S':则该字符串用于添加一个Sheet类对象并添加到Sheet类的ArrayList中,运用正则表达式"#S:\s(\d+)\s+(\w)\s(#A:\s(\d+-?[^#]))"对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,同上进行各种操作(大多都是运用substring()、split()......在此省略赘述,下同),得到Sheet类对象所需要的属性并以此添加Sheet类的ArrayList的新Array。
【7】charAt(1)为'D':则该字符串用实例化一个int类对象:delete。运用正则表达式"#D:\sN-\d+"对该条字符串进行匹配,如果不匹配,则System.out.printf("wrong format:%s\n",information[i]);(指明该条字符串是错误格式),如果匹配,同上进行各种操作,实例化delete。
4.排序:先进行排序,运用接口对答卷类进行排序(优先级为学号、试卷号,按从小到大的顺序先按学号排序,再按试卷号)。
5.进行判题操作:对Sheet类的ArrayList的循环遍历中对Student类的ArrayList进行循环遍历,且与此同时在对Student类的遍历时也对Sheet类的ArrayList进行遍历,即三层内嵌循环。该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。格式:"alert: full score of test paper"+试卷号+" is not 100 points"判题其实就是进行匹配:首先Question类Array匹配Answer类Array,Choice_Question类Array匹配Choice_Answer类Array,Fill_Question类Array匹配Fill_Answer类Array(前提是试卷号和答卷号要匹配,如果有试卷号存在但是对应答卷号不存在的情况,则输出”the test paper number does not exist”,答卷中的答案不用输出。如果有答卷号存在但是对应试卷号不存在的情况,则输出”the test paper number does not exist”,答卷中的答案不用输出),试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。如果输入的答案信息少于试卷的题目数量,每一个缺失答案的题目都要输出"answer is null" 。如果一切正常,那就进行判题,根据得分情况对每个同学的每张试卷进行评分与输出。(答题人姓名,学号,题目回答情况和得分都要输出)。
家居强电电路模拟程序-1:
(1)类的设计思路图
(2)设计具体思路:
1.字符串录入:先创建一个String类的数组,用于储存输入的所有字符串,直到输入的字符串为"end"为止。以这个String类数组中的字符串为基础,进行处理。
2.对象的创建:创建一条Device类(原件)。
3.各类对象的实例化:根据charAt(1)(字符串第二个字符)对步骤1中所实例化的字符串数组进行分类操作:
【1】charAt(1)为'K':则该字符串用于添加一个Switch类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个Switch类对象,并加入到Device类的ArrayList中去。
【2】charAt(1)为'F':则该字符串用于添加一个DiscreteSpeedController类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个DiscreteSpeedController类对象,并加入到Device类的ArrayList中去。
【3】charAt(1)为'L':则该字符串用于添加一个ContinuousSpeedController类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个ContinuousSpeedController类对象,并加入到Device类的ArrayList中去。
【4】charAt(1)为'B':则该字符串用于添加一个IncandescentLamp类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个IncandescentLamp类对象,并加入到Device类的ArrayList中去。
【5】charAt(1)为'R':则该字符串用于添加一个FluorescentLamp类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个FluorescentLamp类对象,并加入到Device类的ArrayList中去。
【6】charAt(1)为'D':则该字符串用于添加一个Fan类对象并添加到Device类的ArrayList中,**截取指定字符并进行类型转化,以此实例化int number,用以实例化一个Fan类对象,并加入到Device类的ArrayList中去。
4.电路状况的确定:根据charAt(0)(字符串第一个字符)和charAt(1)(字符串第二个字符)对步骤1中所实例化的字符串数组进行分类操作:
【1】charAt(0)为'#'且charAt(1)为'K':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为Switch类且其num属性与改int类值相等,则改变一次该Switch类ArrayList的state属性(若此时为0,则改变为1.反之亦然,0为关闭,1为打开)。
【2】charAt(0)为'#'且charAt(1)为'F':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为DiscreteSpeedController类且其num属性与改int类值相等,根据该字符串的charAt(3)来判断该Array的initionSpeedLevel该有的变化(charAt(3)为'-'则减小一档。charAt(3)为'+',则加一档。特别注意此次包括0共四档,若已经为0档,则减一档还是0档。若已经为3档,则加一档仍未3档)。
【3】charAt(0)为'#'且charAt(1)为'L':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为FluorescentLamp类且其num属性与改int类值相等,则截取指定的第二个字符并转为double类,并将该Array的range属性设置为该double数据。
5.原件排序:对Device类对象实现接口,用于排序:对Device类ArrayList先根据每个原件的type属性再根据num属性进行从大到校排序(每一个原件所对应的类都有一个type属性,按照Switch、DiscreteSpeedController、ContinuousSpeedController、IncandescentLamp、FluorescentLamp、Fan的顺序不断增大)
6.输出原件的运行情况:对经过排序后的ArrayList进行遍历,对每一个Array的运行情况进行输出(Switch、DiscreteSpeedController、ContinuousSpeedController这三类对象会影响其他对象,Switch对象会影响电路的开关,其他两个会影响电路的运行电压,需要根据物理知识设定程序的运行逻辑)。
家居强电电路模拟程序-2:
(1)类的设计思路图:
(2)程序设计具体思路:
1.字符串录入:先创建一个String类的数组,用于储存输入的所有字符串,直到输入的字符串为"end"为止。以这个String类数组中的字符串为基础,进行处理。
2.对象的创建:创建一条总Device类(原件)、副Device类(原件)和Circuit类(串联电路)ArrayList。
3.各类对象的实例化:根据charAt(1)(字符串第二个字符)对步骤1中所实例化的字符串数组进行分类操作:
【1】charAt(1)为'K':则该字符串用于添加一个Switch类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个Switch类对象,并加入到Device类的ArrayList中去。
【2】charAt(1)为'F':则该字符串用于添加一个FControl类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个FControl类对象,并加入到Device类的副ArrayList中去。
【3】charAt(1)为'L':则该字符串用于添加一个LControl类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个LControl类对象,并加入到Device类的副ArrayList中去。
【4】charAt(1)为'B':则该字符串用于添加一个BLight类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个BLight类对象,并加入到Device类的副ArrayList中去。
【5】charAt(1)为'R':则该字符串用于添加一个RLight类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个RLight类对象,并加入到Device类的副ArrayList中去。
【6】charAt(1)为'D':则该字符串用于添加一个Fan类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个Fan类对象,并加入到Device类的副ArrayList中去。
【7】charAt(1)为'A':则该字符串用于添加一个AFan类对象并添加到Device类的ArrayList中,截取指定字符并进行类型转化,以此实例化int number,用以实例化一个AFan类对象,并加入到Device类的副ArrayList中去。
【8】charAt(1)为'T'且i<字符串的个数:根据特征字符,确定是将哪个原件加入到副ArrayList中去。
【9】charAt(1)为'M':根据特征字符确定,是哪个Circuit类对象加入到Circuit类ArrayList中去,并以此Circuit类ArrayList创建并实例化一个MCircuit类对象。
【8】charAt(1)为'T'且i=字符串的个数:根据特征字符,确定是将哪个原件加入到总ArrayList中去。
4.电路状况的确定:根据charAt(0)(字符串第一个字符)和charAt(1)(字符串第二个字符)对步骤1中所实例化的字符串数组进行分类操作:(注:遍历时会有Array为Mcircuit类,需要对其Circuit类属性进行遍历,其中每个Circuit类Array也需要进行遍历)
【1】charAt(0)为'#'且charAt(1)为'K':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为Switch类且其num属性与改int类值相等,则改变一次该Switch类ArrayList的state属性(若此时为0,则改变为1.反之亦然,0为关闭,1为打开)。
【2】charAt(0)为'#'且charAt(1)为'F':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为DiscreteSpeedController类且其num属性与改int类值相等,根据该字符串的charAt(3)来判断该Array的initionSpeedLevel该有的变化(charAt(3)为'-'则减小一档。charAt(3)为'+',则加一档。特别注意此次包括0共四档,若已经为0档,则减一档还是0档。若已经为3档,则加一档仍未3档)。
【3】charAt(0)为'#'且charAt(1)为'L':截取指定字符并转化为int形式,如若在对Device类的字符串的遍历中有Array为FluorescentLamp类且其num属性与改int类值相等,则截取指定的第二个字符并转为double类,并将该Array的range属性设置为该double数据。
5.原件状态确定:根据每一个原件的状态,设计物理逻辑编写程序,确定每一个原件的运行成果。
6.原件集合:创建一个新的Device类ArrayList(此后叫新Device类ArrayList),对经过排序后的ArrayList进行遍历将所有的Array加入到新ArrayList中去(如果Array为Mcircuit类,则先对其所包含的Circuit类属性进行遍历,其Circuit类属性也需要遍历,将其所有的Array加入到新ArrayList中去)
7.原件排序:对Device类对象实现接口,用于排序:对Device类新ArrayList先根据每个原件的type属性再根据num属性进行从大到校排序。(每一个原件所对应的类都有一个type属性,按照Switch、DiscreteSpeedController、ContinuousSpeedController、IncandescentLamp、FluorescentLamp、Fan的顺序不断增大)
8.输出原件的运行情况:对经过排序后的新ArrayList进行遍历,对每一个Array的运行情况进行输出。
三.踩坑心得
(1)踩坑:家居强电电路模拟程序-1:未考虑并联电路某一电路断开,电阻设定为0,会导致电流无限大(调速器的range为0也算电路断开)。
解决方法:考虑并联电路某一电路断开的情况。
数据:
T1:[IN K1-1] [K1-2 A1-1] [A1-2 OUT]
T2:[IN K2-1] [K2-2 B2-1] [B2-2 A2-1] [A2-2 OUT]
T3:[IN K3-1] [K3-2 D3-1] [D3-2 A3-1] [A3-2 OUT]
M1:[T1 T2 T3]
T4:[VCC F1-1] [F1-2 M1-IN] [M1-OUT R1-1] [R1-2 GND]
K2
K3
F1+
F1+
F1+
end
改正后测试结果:
@K1:turned on
@K2:closed
@K3:closed
@F1:3
@B2:79
@R1:180
@D3:0
@A1:0
@A2:160
@A3:0
(2)踩坑:家居强电电路模拟程序-1:最开始没有考虑分段调速器档次为0不能减小,档次为3不能增大。
解决方法:考虑档次为0不能再减小,档次为3不能再增大。
数据:
T1:[IN K1-1] [K1-2 A1-1] [A1-2 OUT]
T2:[IN K2-1] [K2-2 B2-1] [B2-2 A2-1] [A2-2 OUT]
T3:[IN K3-1] [K3-2 D3-1] [D3-2 A3-1] [A3-2 OUT]
M1:[T1 T2 T3]
T4:[VCC F1-1] [F1-2 M1-IN] [M1-OUT R1-1] [R1-2 GND]
K1
K2
K3
F1+
F1+
F1+
F1+
end
改正后测试结果:
@K1:closed
@K2:closed
@K3:closed
@F1:3
@B2:73
@R1:180
@D3:0
@A1:260
@A2:80
@A3:0
(3)踩坑:家居强电电路模拟程序-2未考虑并联电路所有的路是断开的会导致整条电路是断开的。
解决方法:考虑并联电路所有电路断开的情况。
数据:
T1:[IN K1-1] [K1-2 A1-1] [A1-2 OUT]
T2:[IN K2-1] [K2-2 B2-1] [B2-2 A2-1] [A2-2 OUT]
T3:[IN K3-1] [K3-2 D3-1] [D3-2 A3-1] [A3-2 OUT]
M1:[T1 T2 T3]
T4:[VCC F1-1] [F1-2 M1-IN] [M1-OUT R1-1] [R1-2 GND]
F1+
F1+
F1+
end
改正后测试结果:
@K1:turned on
@K2:turned on
@K3:turned on
@F1:3
@B2:0
@R1:0
@D3:0
@A1:0
@A2:0
@A3:0
(4)踩坑:未考虑一条并联电路可以有多条串联电路,不止两条。
解决方法:考虑并联电路多电路的情况。
数据:
T1:[IN K1-1] [K1-2 A1-1] [A1-2 OUT]
T2:[IN K2-1] [K2-2 B2-1] [B2-2 A2-1] [A2-2 OUT]
T3:[IN K3-1] [K3-2 D3-1] [D3-2 A3-1] [A3-2 OUT]
M1:[T1 T2 T3]
T4:[VCC F1-1] [F1-2 M1-IN] [M1-OUT R1-1] [R1-2 GND]
K1
K2
K3
F1+
F1+
F1+
end
改正后测试结果:
@K1:closed
@K2:closed
@K3:closed
@F1:3
@B2:73
@R1:180
@D3:0
@A1:260
@A2:80
@A3:0
四.改进建议
(1)改用hashmap()
(2)学习使用getClass()尝试减少代码量
五.总结
(1)首先,这三题为近几周的主要任务,也是开始学习Java以来第二个比较耗时的编程任务,它们不仅仅考验了我们学生之前在前段时间java语言学习的成果。还在其中大量运用了我们在java语言中新学习到的知识如多态与继承、实例转换等等。
(2)其次,在前段时间里,我明显认识到了自己的不足不仅体现在学习能力上还体现在学习态度上,很多东西都是老师和同学指导以后才理解的,自主学习能力较少,急需改正,因此我这段时间的学习并没有松懈,而是努力赶上其他同学的步伐,因此这段时间有一定的提高,做题不再那么依靠同学和老师了。
(3)然后,在这几周中,我进一步了解了Java编程的要求和形式。同时对于面向对象等原则的认识逐渐清晰,对接口和抽象类这一知识点有了更加深入的了解。
(4)此外,我仍然认为时间十分重要。在课程方面,虽然近期晚自习多了,但是我还是建议学校可以试着调整课程的安排,让学生们在学习过程中可以尽可能的线下交流、共同讨论、一起克服难题。在作业方面,我曾经希望老师可以明确作业的要求,测试点的要求希望可以更加清晰,但是我现在发现,程序需要自己去完善,自己去想有什么需要改进的地方,因为建议老师只要表明有几个测试点就行了,不用标明测试点的通过方法。在实验方面,我没有什么建议,比较满意。
(5)最后,我希望自己可以保持现在的学习状态,甚至,更加努力,不白白浪费自己的大学时光!