题目集4~6的总结

一、前言

1、题目集4是第四次答题判题程序,在前面几次的基础上加了选择题题目信息和填空题题目信息。

(1)知识点

这次我使用了继承和多态来处理题目信息,对多种类型的题目(选择题、填空题等)进行处理,要求根据不同的标准判断答案是否正确,根据题目的标准与学生提交的答案进行比对,输出判分结果。对选择题、多选题以及填空题的得分处理需要依据具体要求(如完全正确、部分正确、错误或空白答案),对答案的判定不仅限于是否完全匹配,还包括对部分正确答案的评定(多选题和填空题)。

(2)题量

题目类型多样,包括选择题、填空题和判断题等,每种题型需要单独的判断和分值计算方法。输入中包含试卷、题目信息、答卷以及删除信息,程序需要正确处理这些信息。如果包含多个试卷,多个学生以及不同类型的题目,数据量和处理的复杂度将显著增加。

(3)难度

中等难度:主要考察数据的格式输入与解析能力,需要对题目信息、学生信息以及答卷信息之间的关系建立正确的映射。对题目删除、答案判定(特别是多选和填空题的部分正确情况)、以及异常情况的处理要求较高,需要编写完整的判分和格式检查逻辑。

2、题目集5是全新的题目,是一个家居强电电路模拟程序。

(1)知识点

这次我还是使用了继承和多态,电路设备类:描述所有电路设备的公共特征。受控设备类、控制设备类:对应受控、控制设备。本题模拟的控制设备包括:开关、分档调速器、连续调速器。本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。

(2)题量

只包含1条简单的串联电路,题量较少,重点在于理解和实现基本的控制逻辑。

(3)难度

任务相对简单,关注设备的基本行为,如开关控制、调速器的档位变化等。难度主要体现在理解设备之间的简单连接和开关、调速器对受控设备的影响。

3、题目集6是第二次家居强电电路模拟程序,在上次基础上加了并联电路。

(1)知识点

在上一次的基础上需要考虑电阻,知道电压、电流的传输与计算,了解设备之间电位差与设备工作状态的关系,尤其是如何根据设备的电位差计算受控设备的状态。电路中的短路如果不会在电路中产生无穷大的电流烧坏电路,都是合理情况,在本题测试点的考虑范围之内。

(2)题量

开始引入并联电路,难度稍增,题目量也适度增加。

(3)难度

引入了并联电路的概念,并且需要计算串联电路和并联电路之间的电压、电流分配,增加了对电路基础知识的理解和运用。需要理解如何在并联电路中处理多个电路之间的交互作用,进一步提高了计算和逻辑的复杂度。

二、第四次答题判题程序

1.需求分析

这一次的答题程序在上一次的基础上增加了选择题题目信息和填空题题目信息。

填空题和多选题输出:输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。

多选题给分方式:答案包含所有正确答案且不含错误答案给满分;包含一个错误答案或完全没有答案给0分;包含部分正确答案且不含错误答案给一半分,如果一半分值为小数,按截尾规则只保留整数部分。

填空题给分方式:答案与标准答案内容完全匹配给满分,包含一个错误字符或完全没有答案给0分,包含部分正确答案且不含错误字符给一半分,如果一半分值为小数,按截尾规则只保留整数部分。

2.程序分析

这次答题判题程序我设计了11个类,在上一次代码的基础上增加了普通题目类,选择题题目类和填空题题目类,新加入的类继承题目类的属性和方法。

题目类Topic
这个类里面主要是用来储存题目的题号,题目还有标准答案。
set()和get()方法,用来更改储存的内容和获取储存的内容。
类的空参和有参构造,用来初始化储存的内容。
judgment()方法,用来判断答案是否和标准答案一致。

普通题目类Problem
这个类继承了题目类的属性和方法。
重写了judgment()方法,判断答案是否和标准答案一致。

选择题题目类ChoiceQuestions
这个类继承了题目类的属性和方法。
重写了judgment()方法,判断答案是否和标准答案一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。

填空题题目类BlanksQuestions
这个类继承了题目类的属性和方法。
重写了judgment()方法,判断答案是否和标准答案一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。

试卷类Paper
这个类主要是储存整个试卷题目的信息,里面有一个存储题目的哈希表,用来储存题目,有一个存储试卷号的哈希表,用来储存试卷分数。
getquestions()方法,用来获取相应题目信息。
savequestion()方法,用来向试卷里的题目的哈希表中存放题目。
save()方法,用来向试卷里的题目分数的哈希表中存放试卷号的分数。
getPoint()方法,用来获取相应试卷的分数。

答卷类Answer
这个类主要是用来存储答题人信息,有答卷的列表属性用来储存每一张答卷,一个学生信息的列表用于储存学生信息。
空参和有参构造,可以初始化试卷类的对象。
save()方法,用来存储答案信息。
printfout()方法,用来输出题目的答题信息,还有答题结果。
savestudent()方法,用来存储学生信息。

题目分值类Score
这个类主要是用来储存单个题目的分值和题号。
有参构造,可以初始化试卷类的对象。
get()方法,获取题目的分值和题号。

试卷号类Points
这个类主要是用来存储你分值的试卷号是哪个,里面有一个存储每一题分值的列表。
gettotal()方法,用来计算一整张试卷的分值,用于判断试卷是否有100分。
saves()方法,用于使用列表存储每一题的分值。
get()方法,可以获取特定题目的分值。

答案类Answer
这个类主要是用来存储答题信息,有答案的列表属性用来储存每一题答案。
save()方法,用来存储答题信息。
getAnswer()方法,用来获取答题信息。
getNumber方法,获取答案对应的试卷号。

学生类Student
这个类是用来存储学生学号和姓名。
无参和有参构造,可以初始化试卷类的对象。
getId()方法,获取学生学号。
getName()方法,获取学生姓名。

主类Main
这个类是程序的服务入口,程序的输入输出都是在这个main方法中执行,通过键盘输入,获取键盘的消息,解析这个消息,首先判断这个符不符合格式。不符合就有提示,内容符合的话再判断它是题目,答案,学生,删除还是试卷分值信息,然后将它存储到相应的类中,最后再调用答卷类中的输出方法,输出相应的内容。

3.类图

4.关键代码讲解

for (int i = 0; i < str1.length; i++) {
     str = "false";
     for (int j = 0; j < str2.length; j++) {
        if(str1[i].equals(str2[j])) {
           str = "partially correct";
           break;
         }
     }
     if(str.equals("false")){
          break;
     }
     if(str1.length==str2.length&&i==str1.length-1){
         str = "true";
    }
}

选择题和填空题的判题方法,判断结果除了true、false,增加一项”partially correct”表示部分正确。

5.采坑心得

(1)遇到的问题一

一开始出现了格式错误,但我测试的好多点都没找到,最后发现如果选择题的答案后面有好多空格,输出的时候只删一个空格。

测试点

#N:1 #Q:1+1= #A:2
#Z:2 #Q:党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信 #A:A B C D
#T:1 1-5 2-9
#X:20201103 Tom
#S:1 20201103 #A:1-5 #A:2-A C   
end

正确输出

alert: full score of test paper1 is not 100 points
1+1=~5~false
党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信~A C  ~partially correct
20201103 Tom: 0 4~4

解决方法:输入时只去除一个空格存放,判断去除所有空格,输出时输出存放的数据。

(2)遇到的问题二

如果填空题答案的顺序不同,我就会无法判断正确,因为我是看答案的字符串是否是标准答案的子串来判断。

测试点

#N:1 #Q:1+1= #A:2
#K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
#T:1 1-5 2-10
#X:20201103 Tom
#S:1 20201103 #A:1-5 #A:2-七弦琴或瑶琴
end

解决方法:将答案和标准答案用split()分隔开来一个一个判断。

6.改进建议

当前系统的设计中,Topic 类和其子类(如 Problem, ChoiceQuestions, BlanksQuestions)具有相似的结构,可以通过抽象类或接口来提取公共功能,这样能够减少代码重复,提高系统的可扩展性和维护性。

当前代码中的输入和输出处理较为简单,缺乏对用户输入的验证,容易出现无效数据的情况。为了提升系统的健壮性,可以添加更多的 异常处理 和 输入验证。

当前评分和试卷管理的代码较为简单,评分逻辑可能较为局限,且没有考虑到更多复杂的评分规则。可以通过增强 评分管理 和 试卷管理 的功能,支持更多的评测标准。

三、第一次家居强电电路模拟程序

1.需求分析

本题涉及模拟电路中的设备,通过连接信息和调节信息,计算出设备的工作状态或参数输出。需要特别注意设备的输入输出电压、调速器的档位转换、灯具亮度的计算及风扇的转速。

只有一条线路,所有元件串联,只包含1个受控元件,不用计算电流,之后的电路计算要包含电流、电阻等电路参数。

2.程序分析

Device 类(抽象类)
数据成员:
String name: 设备名称
int id: 设备ID
方法成员:
构造方法 Device(), Device(String name, int id)
String getName(): 获取设备名称
int getId(): 获取设备ID
void setId(int id): 设置设备ID

ControlDevice 类(继承自 Device,抽象类)
数据成员: 继承自 Device 类
方法成员:
public abstract void setState(String num): 设置控制设备的状态(具体实现由子类提供)

Switch 类(继承自 ControlDevice)
数据成员:
boolean state: 设备状态,true 表示开,false 表示关
方法成员:
构造方法 Switch(), Switch(String name, int id)
boolean isState(): 获取当前开关状态
String getState(): 获取当前开关的描述(“closed” 或 “turned on”)
void setState(String num): 切换开关状态

BinningGovernor 类(继承自 ControlDevice)
数据成员:
int gears: 当前档位
double voltage: 输出电压
方法成员:
构造方法 BinningGovernor(), BinningGovernor(String name, int id)
double getOutputVoltage(double num): 根据档位和输入电压计算输出电压
int getGears(): 获取当前档位
void setGears(int gears): 设置档位
void setState(String num): 根据输入参数 + 或 - 调整档位

ContinuousGovernor 类(继承自 ControlDevice)
数据成员:
double gears: 当前调速档位(可以是小数)
double voltage: 输出电压
方法成员:
构造方法 ContinuousGovernor(), ContinuousGovernor(String name, int id)
double getOutputVoltage(double num): 根据档位和输入电压计算输出电压
double getGears(): 获取当前调速档位
void setGears(double gears): 设置调速档位
void setState(String num): 设置调速档位(由用户输入)

ControlledDevice 类(继承自 Device,抽象类)
数据成员: 继承自 Device 类
方法成员:
public abstract void setPotential(double potential): 设置电压或电势

Incandescent 类(继承自 ControlledDevice)
数据成员:
int brightness: 白炽灯的亮度
方法成员:
构造方法 Incandescent(), Incandescent(String name, int id)
int getBrightness(): 获取白炽灯亮度
void setBrightness(int brightness): 设置白炽灯亮度
void setPotential(double potential): 根据电压设置白炽灯亮度

Fluorescent 类(继承自 ControlledDevice)
数据成员:
int brightness: 日光灯的亮度
方法成员:
构造方法 Fluorescent(), Fluorescent(String name, int id)
int getBrightness(): 获取日光灯亮度
void setBrightness(int brightness): 设置日光灯亮度
void setPotential(double potential): 根据电压设置日光灯亮度

CeilingFan 类(继承自 ControlledDevice)
数据成员:
int speed: 吊扇的转速
方法成员:
构造方法 CeilingFan(), CeilingFan(String name, int id)
int getSpeed(): 获取吊扇转速
void setPotential(double potential): 根据电压设置吊扇转速

Output 类
数据成员:
double voltage: 当前输出电压
List switches: 存储所有开关设备
List binning: 存储所有分档调速器设备
List continuous: 存储所有连续调速器设备
List incandes: 存储所有白炽灯设备
List fluores: 存储所有日光灯设备
List fan: 存储所有吊扇设备
Map<String, Device> circuit: 存储所有设备的映射关系
方法成员:
构造方法 Output(Map<String, Device> circuit)
void setSwitches(): 根据设备名称对各类设备进行分类,并按ID排序
void control(): 控制设备的电压输出
void output(): 输出所有设备的状态信息

Main 类
方法成员:
public static void main(String[] args): 主程序,负责从用户输入读取数据并执行相应操作

总结

数据成员(属性):每个设备类通常有一个 name 和 id,还有根据设备类型不同的特定属性(如开关的 state,调速器的 gears,灯具的 brightness 等)。

方法成员(方法):设备类包含用于设置设备状态、获取设备属性值、控制设备行为的方法。在 Output 类中,主要的方法是 setSwitches()、control() 和 output(),用于管理设备的状态、控制电压输出、以及输出设备状态。

3.类图

4.关键代码讲解

int key=1;
for (Switch aSwitch : switches) {
    if (!aSwitch.isState()) {
        key = 0;
        break;
    }
}
if(key==1) {
   if(!binning.isEmpty()){
       voltage = binning.get(0).getOutputVoltage(220.00);
   }else if(!continuous.isEmpty()){
       voltage = continuous.get(0).getOutputVoltage(220.00);
   }else{
       voltage = 220.00;
   }
 }else{
    voltage=0;
}

首先判断串联电路中是否有开关是打开的,如果开关有打开那么整个电压直接为0,如果都是关闭的,那么就判断是否有调速器,根据调速器改变电压。

5.采坑心得

(1)遇到的问题一

一开始我以为分档调速器和风扇调速一样,调到3档后在加一档会变为0档,后面发现是不变。

解决方法:加的时候判断是否是小于三档,是的话就加,并且减的时候判断是否大于零档,是的话就减。

(2)遇到的问题二

一开始我是通过电压一个设备一个设备传下去,没有考虑到开关在后面这种情况,只去判断当前设备状态,这使得当后面开关如果是打开的,那么这会使整条电路电压为0。

测试点

[VCC D1-1]
[D1-2 K2-1]
[K2-2 GND]
end

正确输出

@K2:turned on
@D1:0

解决方法:我先遍历整条电路判断所有开关的状态,然后再去算电压。

6.改进建议

这次代码我只考虑了串联,没有考虑并联,并且只能有一条串联,是专门为了这一次而解决的,所以我下一次写代码的时候,到时候要修改的地方就很多,要考虑到串联这种情况,而且还有可能会出现短路,都要考虑进去,这一次不需要使用电阻,所以我的代码也没有去考虑,这是之后的程序,需要去考虑的。

当前的用户输入解析通过字符串截取和分割来获取信息,代码逻辑较为复杂。考虑将解析过程封装成专门的函数或类,提供清晰的输入接口和验证。

当前的设计使用了抽象类来描述设备,但我们可以通过接口来进一步解耦 ControlDevice 和 ControlledDevice 类,使得不同设备的扩展更加灵活。可以创建 Controllable 接口和 DeviceState 接口,来让设备类更明确地定义其行为。

四、第二次家居强电电路模拟程序

1.需求分析

依据电源输入和设备连接关系,逐步计算每个设备的输入电压。根据输入的调节信息(如开关调节、调速器调整),更新设备的状态或输出参数。

本题中的并联信息所包含的串联电路的信息都在并联信息之前输入,不考虑乱序输入的情况。

串联线路信息:用于记录一段串联电路的元件与连接信息。

并联线路信息:用于记录一段并联电路所包含的所有串联电路信息。

2.程序分析

这一次的家电强电电路模拟程序我在上一次的基础上添加了串联类和并联类

Device 类
数据成员:
String name: 设备名称
int id: 设备ID
double resistance: 设备的电阻
double potential: 设备的电势
方法成员:
构造方法 Device() 和 Device(String name, int id)
Getter 和 Setter 方法:
getName(), getId(), setId(int id)

ControlDevice 类(继承自 Device 类)
数据成员: 继承自 Device 类,当前无新增数据成员。
方法成员:
abstract void setState(String num): 设置设备状态(由子类实现)

Switch 类(继承自 ControlDevice 类)
数据成员:
boolean state: 状态(开或关)
方法成员:
boolean isState(): 返回开关状态
String getState(): 获取开关状态的字符串描述("closed" 或 "turned on")
void setState(String num): 切换状态(开/关)

BinningGovernor 类(继承自 ControlDevice 类)
数据成员:
int gears: 控制档位
double voltage: 输出电压
方法成员:
double getOutputVoltage(double num): 根据档位计算输出电压
void setVoltage(int voltage): 设置输出电压
int getGears(), void setGears(int gears): 获取和设置档位
void setState(String num): 增加或减少档位(根据 "+" 或 "-")

ContinuousGovernor 类(继承自 ControlDevice 类)
数据成员:
double gears: 调速档位(连续)
double voltage: 输出电压
方法成员:
double getOutputVoltage(double num): 根据档位计算输出电压
double getGears(), void setGears(double gears): 获取和设置档位
void setState(String num): 设置档位(连续)

ControlledDevice 类(继承自 Device 类)
数据成员: 继承自 Device 类,当前无新增数据成员。
方法成员:
abstract void setPotential(): 设置设备的电势(由子类实现)

Incandescent 类(继承自 ControlledDevice 类)
数据成员:
int brightness: 亮度
方法成员:
int getBrightness(), void setBrightness(int brightness): 获取和设置亮度
void setPotential(): 根据电势设置亮度

Fluorescent 类(继承自 ControlledDevice 类)
数据成员:
int brightness: 亮度
方法成员:
int getBrightness(), void setBrightness(int brightness): 获取和设置亮度
void setPotential(): 根据电势设置亮度

CeilingFan 类(继承自 ControlledDevice 类)
数据成员:
int speed: 风扇速度
方法成员:
int getSpeed(): 获取风速
void setPotential(): 根据电势设置风速

Floorfan 类(继承自 ControlledDevice 类)
数据成员:
int speed: 风扇速度
方法成员:
int getSpeed(): 获取风速
void setPotential(): 根据电势设置风速

Concatenation 类(继承自 Device 类)
数据成员:
Map<String, Device> tandem: 用于保存串联的设备
方法成员:
void save(String num, Device s): 保存设备到串联中
Map<String, Device> getTandem(): 获取所有串联的设备

Parallel 类(继承自 Device 类)
数据成员:
Map<String, Concatenation> circuit: 用于保存并联的电路
方法成员:
void save(String num, Concatenation s): 保存串联到并联电路中

Output 类
数据成员:
double voltage: 电压
double resist: 电阻
List switches: 存储所有开关设备
List binning: 存储所有分档调速器
List continuous: 存储所有连续调速器
List incandes: 存储所有白炽灯
List fluores: 存储所有日光灯
List fan: 存储所有吊扇
List floor: 存储所有落地扇
Map<String, Parallel> circuit: 存储所有并联电路
Map<String, Concatenation> concatens: 存储所有串联电路
Map<String, Device> major: 存储主电路设备
方法成员:
void save(String num, Parallel p): 保存并联电路
void setresistance(): 计算电路的电阻
void control(): 控制电路的工作状态,设置电势
void setSwitches(): 将设备分类到不同的列表中
void output(): 输出设备的状态

Main 类
方法成员:
public static void main(String[] args): 程序入口,负责读取输入并创建设备、连接电路,并输出最终的电路状态。

3.类图

4.关键代码讲解

这个函数是用来计算并联电路的电阻的,并且还可以判断里面是否发生短路这种情况。通过循环先计算串联里面的电阻,然后再计算并联的电阻。

计算主电路的电阻,然后在通过分压法来求各设备的电压,然后算出并联电路的电压之后,再计算并联里的串联电路的电压,然后计算串联里设备的电压。

5.采坑心得

遇到的问题

一开始写代码的时候,我没有考虑到短路这种情况,所以会出问题。

解决方法:在算电阻的时候将短路这种情况加进去,如果是发生短路,那么就让电阻为-1,之后计算电压的时候再判断一下。

6.改进建议

(1)可以通过引入更多的接口或抽象类来进一步规范设备和控制设备的设计。比如所有的“控制设备”(如Switch、BinningGovernor、ContinuousGovernor等)可以实现一个统一的ControlDevice接口,进一步抽象出公共行为。同样,所有“受控设备”可以实现ControlledDevice接口。这样不仅提高了扩展性,也可以简化代码的管理。

(2)Output类的功能过于庞大,负责设备的创建、控制、计算和输出结果等多个方面,建议进行拆分,例如:
CircuitController:负责控制设备的开关和状态。
VoltageCalculator:负责电压、电阻的计算。
ResultOutput:负责输出最终的计算结果。
这些拆分可以让每个类更加单一职责,代码更加清晰。

五、总结

通过这三次题目集,我对Java语言有了更深入的了解,掌握了面向对象编程的基本思想和方法,提高了编程能力和解决问题的能力,我对继承和多态的知识更加了解。通过将不同类型的设备(开关、调速器、灯具等)分别封装到不同的类中,我学会了如何设计 模块化 的系统。每个类负责自己独立的功能,增强了代码的可维护性和可扩展性。例如,当需要新增其他设备类型时,只需在现有基础上扩展新的类,而无需修改已有的代码。通过合理地设计继承体系和接口,我学会了如何将公共功能提取到基类中,避免代码重复,提高了代码的复用性。通过解决这三次题目集,我不仅加深了对面向对象编程的理解,还在java数据结构与算法的应用、输入输出处理、精度控制等方面获得了实践经验。

posted @   李英杰`  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示