I.
第四次答题判断:在前三次答题判断的基础之上添加了多选题,填空题,同时要求多张试卷并排序。
1.输入选择题题目信息:
题目信息为独行输入,一行为一道题,多道题可分多行输入。
格式:"#Z:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式基本的约束与一般的题目输入信息一致。
新增约束:标准答案中如果包含多个正确答案(多选题),正确答案之间用英文空格分隔。
输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。
多选题给分方式:
答案包含所有正确答案且不含错误答案给满分;包含一个错误答案或完全没有答案给0分;包含部分正确答案且不含错误答案给一半分,如果一半分值为小数,按截尾规则只保留整数部分。
2.输入填空题题目信息
题目信息为独行输入,一行为一道题,多道题可分多行输入。
格式:"#K:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式基本的约束与一般的题目输入信息一致。
例如:#K:2 #Q:古琴在古代被称为: #A:瑶琴或七弦琴
填空题输出:
输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。
填空题给分方式:
答案与标准答案内容完全匹配给满分,包含一个错误字符或完全没有答案给0分,包含部分正确答案且不含错误字符给一半分,如果一半分值为小数,按截尾规则只保留整数部分。
3、输出顺序变化
只要是正确格式的信息,可以以任意的先后顺序输入各类不同的信息。比如试卷可以出现在题目之前,删除题目的信息可以出现在题目之前等。
4、多张试卷信息
本题考虑多个同学有多张不同试卷的答卷的情况。输出顺序优先级为学号、试卷号,按从小到大的顺序先按学号排序,再按试卷号。
对于多选题与填空题的部分正确的特殊判定:
1.多选题(存在选项乱序输入的情况):
先判断是否与标准答案一致,如果一致则:返回全部分数。
再将答案分成一个字符数组:
遍历该数组判断是否每个选择的答案都被标准答案包含:
如果每个选择的答案都被正确答案包含而且数量一致则:返回全部分数。
如果出现有的答案不被标准答案包含则:返回0分。
除此之外:返回一半分数。
示例代码如下:
点击查看代码
public int check(String answer, int score) {
if (answer.equals(super.getAnswer())) {
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "true");
return score;
} else {
int flag = 0;
String[] a = answer.split(" ");
int x = super.getAnswer().split(" ").length;
for (int i = 0; i < a.length; i++) {
if (super.getAnswer().contains(a[i])) {
flag++;
}
}
if (flag == x && x == a.length) {
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "true");
return score;
}
for (int i = 0; i < a.length; i++) {
if (!super.getAnswer().contains(a[i])) {
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "false");
return 0;
}
}
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "partially correct");
return score / 2;
}
}
点击查看代码
public int check(String answer, int score) {
if (answer.equals(super.getAnswer())) {
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "true");
return score;
} else {
String[] a = answer.split("或");
for (int i = 0; i < a.length; i++) {
if (!super.getAnswer().contains(a[i])) {
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "false");
return 0;
}
}
System.out.println(super.getContent().trim() + "~" + answer.trim() + "~" + "partially correct");
return score / 2;
}
}
其他思路与前两次基本一致
类图如下:
II.
OOP5:家居强电电路模拟程序-1
智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。请根据如下要去设计一个智能家居强电电路模拟系统。
1、控制设备模拟
本题模拟的控制设备包括:开关、分档调速器、连续调速器。
开关:包括0和1两种状态。
开关有两个引脚,任意一个引脚都可以是输入引脚,而另一个则是输出引脚。开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。
分档调速器
按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
连续调速器
没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。输出电位为档位参数乘以输入电压。
所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。
所有控制设备的初始状态/档位为0。
控制设备的输入引脚编号为1,输出引脚编号为2。
2、受控设备模拟
本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
灯有两种工作状态:亮、灭。在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
风扇在接电后有两种工作状态:停止、转动。风扇的转速会因引脚的电位差的不同而有区别。
本次迭代模拟两种灯具。
白炽灯:
亮度在0~200lux(流明)之间。
电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
日光灯:
亮度为180lux。
只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
本次迭代模拟一种吊扇。
工作电压区间为80V-150V,对应转速区间为80-360转/分钟。80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
输入信息:
1、设备信息
分别用设备标识符K、F、L、B、R、D分别表示开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇。
设备标识用标识符+编号表示,如K1、F3、L2等。
引脚格式:设备标识-引脚编号,例如:K1-1标识编号为1的开关的输入引脚。
三种控制开关的输入引脚编号为1,输出引脚编号为2。
受控设备的两个引脚编号分别为1、2。
约束条件:
不同设备的编号可以相同。
同种设备的编号可以不连续。
设备信息不单独输入,包含在连接信息中。
2、连接信息
一条连接信息占一行,用[]表示一组连接在一起的设备引脚,引脚与引脚之间用英文空格" "分隔。
格式: "["+引脚号+" "+...+" "+引脚号+"]"
例如: [K1-1 K3-2 D5-1]表示K1的输入引脚,K3的输出引脚,D5的1号引脚连接在一起。
约束条件:
本次迭代不考虑两个输出引脚短接的情况
考虑调速器输出串联到其他控制设备(开关)的情况
不考虑调速器串联到其他调速器的情况。
不考虑各类控制设备的并联接入或反馈接入。例如,K1的输出接到L2的输入,L2的输出再接其他设备属于串联接线。K1的输出接到L2的输出,同时K1的输入接到L2的输入,这种情况属于并联。K1的输出接到L2的输入,K1的输入接到L2的输出,属于反馈接线。
3、控制设备调节信息
开关调节信息格式:
-#+设备标识K+设备编号,例如:#K2,代表切换K2开关的状态。
分档调速器的调节信息格式:
_#+设备标识F+设备编号+"+" 代表加一档,例如:#F3+,代表F3输出加一档。
_#+设备标识F+设备编号+"-" 代表减一档,例如:#F1-,代表F1输出减一档。
连续调速器的调节信息格式:
_#+设备标识L+设备编号+":" +数值 代表将连续调速器的档位设置到对应数值,例如:#L3:0.6,代表L3输出档位参数0.6。
4、电源接地标识:VCC,电压220V,GND,电压0V。没有接线的引脚默认接地,电压为0V。
输入信息以end为结束标志,忽略end之后的输入信息。
输出信息:
按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇的顺序依次输出所有设备的状态或参数。每个设备一行。同类设备按编号顺序从小到大输出。
输出格式:@设备标识+设备编号+":" +设备参数值(控制开关的档位或状态、灯的亮度、风扇的转速,只输出值,不输出单位)
连续调速器的档位信息保留两位小数,即使小数为0,依然显示两位小数.00。
开关状态为0(打开)时显示turned on,状态为1(合上)时显示closed
如:
@K1:turned on
@B1:190
@L1:0.60
本题不考虑输入电压或电压差超过220V的情况。
本题只考虑串联的形式,所以所有测试用例的所有连接信息都只包含两个引脚
本题电路中除了开关可能出现多个,其他电路设备均只出现一次。
电源VCC一定是第一个连接的第一项,接地GND一定是最后一个连接的后一项。
首先设计电器父类包含name,show方法:
点击查看代码
//A代表所有用电器的父类
class A {
private String name;
public A(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//在父类中定义一个show的空方法并在后续每个子类中进行重写以展示不同元件的不同输出样式
public void show() {
}
}
设计相应的子类继承父类并重写父类中的方法,并定义子类特有的相应的改变状态的方法:
以K:开关,D:吊扇
点击查看代码
//开关
class K extends A {
private boolean stage;
//true代表闭合,false代表断开
public K(String name, boolean stage) {
super(name);
this.stage = stage;
}
public boolean getStage() {
return stage;
}
//这个方法用于修改开关状态
public void changeStage() {
this.stage = !stage;
}
public void setStage(boolean stage) {
this.stage = stage;
}
@Override
public void show() {
if (stage) {
System.out.println("@" + super.getName() + ":" + "closed");
} else {
System.out.println("@" + super.getName() + ":" + "turned on");
}
}
}
//吊扇
class D extends A {
private double speed;
public D(String name, double speed) {
super(name);
this.speed = speed;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public void changeSpeed(double voltage) {
if (voltage < 80) {
this.speed = 0;
} else if (voltage < 150 && voltage >= 80) {
this.speed = (int) (80 + (voltage - 80) * 4);
} else if (voltage > 150) {
this.speed = 360;
}
}
@Override
public void show() {
int x = (int) (this.speed);
System.out.println("@" + super.getName() + ":" + x);
}
}
同时设计一个串联电路类:
点击查看代码
class Line {
private double voltage;
private ArrayList<A> list = new ArrayList<>();
private HashMap<Integer, A> map = new HashMap<>();
public Line() {
}
public Line(double voltage, ArrayList<A> list) {
this.voltage = voltage;
this.list = list;
}
public double getVoltage() {
return voltage;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public ArrayList<A> getList() {
return list;
}
public void setList(ArrayList<A> list) {
this.list = list;
}
//题目要求:按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇的顺序依次输出所有设备的状态或参数。
// 每个设备一行。同类设备按编号顺序从小到大输出。
// 第一次不用考虑同设备不同编号也可以过
//后续要进行排序时将同类设备添加到一个列表中排序即可
public void showAll() {
//按顺序输出所有元件
for (A a : list) {
if (a instanceof K) {
a.show();
}
}
for (A a : list) {
if (a instanceof F) {
a.show();
}
}
for (A a : list) {
if (a instanceof L) {
a.show();
}
}
for (A a : list) {
if (a instanceof B) {
a.show();
}
}
for (A a : list) {
if (a instanceof R) {
a.show();
}
}
for (A a : list) {
if (a instanceof D) {
a.show();
}
}
}
//处理一条电路中各个元件的信息
public void function() {
int flag = 0;
//首先判断电路是否有电流(串联电路中如果有一干路上开关断开则整条电路断路)
//判断一条电路中所有开关是否闭合,如果有一个开关断开,则整条电路断路
for (A a : list) {
if (a instanceof K) {
K k = (K) a;
if (!k.getStage()) {
flag = 1;
break;
}
}
}
if (flag == 1) {
voltage = 0;
}
//处理完开关问题后对各个元件进行处理
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof F) {
F f = (F) list.get(i);
voltage = f.changevoltage(voltage);
}
if (list.get(i) instanceof L) {
L l = (L) list.get(i);
voltage = l.changevoltage(voltage);
}
if (list.get(i) instanceof B) {
B b = (B) list.get(i);
b.changeBrightness(voltage);
list.set(i, b);
}
if (list.get(i) instanceof R) {
R r = (R) list.get(i);
r.changeBrightness(voltage);
list.set(i, r);
}
if (list.get(i) instanceof D) {
D d = (D) list.get(i);
d.changeSpeed(voltage);
list.set(i, d);
}
}
}
类图如下:
根据上述类图的设计可以设计解题思路如下:
1.创建一个串联电路类并初始化电压为220V
2.按照输入信息将输入的电子元件一个一个有序地储存到串联电路中
3.读取输入的控制信息修改控制设备的状态
4.判断电路是否有电流流通(所有开关是否闭合),如果有开关没有闭合则电压为0,遍历串联电路的电子元件列表按题目所给的方式输出所有电子元件的信息
5.如果电路联通,则遍历串联电路的元件列表依照变化的电压得出每个元件的最终数据并输出。
III.
家居强电电路模拟程序-2
在上一次电路模拟的前提下添加了并联电路,同时考虑电阻,加入了用电器-落地扇。
因此在上次基础上:建立一个allLine列表记录处理主电路以外的分支电路
储存多条除了主电路以外的串联电路,供后续并联电路获取组成部分作用
创建一个并联电路类
其中包含根据并联线路的子电路的名称获取子电路组成整个电路,判断该并联电路是否 联通,获取联通电路的总电阻;
代码如下:
点击查看代码
lass parallelConnection {
private String name;
private String[] linename;
public double getPararesistance(ArrayList<Line> alllist) {
int px=0;
double[] x = new double[linename.length];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < alllist.size(); j++) {
if (alllist.get(j).getName().equals(linename[i])) {
if (alllist.get(j).isStage()&&alllist.get(j).getAllresistance()==0) {
px =1;
}else if(alllist.get(j).isStage()&&alllist.get(j).getAllresistance()!=0){
x[i] = alllist.get(j).getAllresistance();
}
else {
x[i] = 0;
}
}
}
}
double sum = 0;
for (int i = 0; i < x.length; i++) {
if (x[i] != 0) {
sum += 1 / x[i];
}
}
if(px==1){
return 0;
}
return 1 / sum;
}
//并联电路是否通路
public boolean ifaccess(ArrayList<Line> alllist) {
int flag = 0;
for (int i = 0; i < linename.length; i++) {
for (int j = 0; j < alllist.size(); j++) {
if (alllist.get(j).getName().equals(linename[i])) {
if (alllist.get(j).isStage() == true) {
flag = 1;
}
}
}
}
if (flag == 0) {
return false;
}
return true;
}
public parallelConnection(String name, String[] linename) {
this.name = name;
this.linename = linename;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getLinename() {
return linename;
}
public void setLinename(String[] linename) {
this.linename = linename;
}
}
设计主电路类
用于记录主电路的信息,其中包含一个stage判断是为单个元件还是一段电路
如果stage为false则代表该部位是单个元件,如果为true则代表为一段并联电路
该类中包含元件类(Ap)以及 并联电路 根据stage判断为其中一类则另一类为null,
代码如下:
点击查看代码
//总电路
class Mainline {
private int num;
private Ap ap;
private double voltage;
private boolean stage;
private String name;
public double getTotalresistance() {
return totalresistance;
}
public void setTotalresistance(double totalresistance) {
this.totalresistance = totalresistance;
}
private double totalresistance;
public Mainline(int num, Ap ap, double voltage, boolean stage, String name) {
this.num = num;
this.ap = ap;
this.voltage = voltage;
this.stage = stage;
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Ap getAp() {
return ap;
}
public void setAp(Ap ap) {
this.ap = ap;
}
public double getVoltage() {
return voltage;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public boolean isStage() {
return stage;
}
public void setStage(boolean stage) {
this.stage = stage;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
设计一个输出的类Forshow 其中包含电器类,以及输出顺序的编号,以及元件序号
在处理完整个电路后遍历主电路将所有处理后的元件添加到Forshow类的列表中进行输出。
以下是在Forshow类的基础上对所有信息的有序输出
点击查看代码
int[] totalnum = new int[8];
for (int i = 0; i < shows.size(); i++) {
for (int j = 1; j <= 7; j++) {
if (shows.get(i).getType() == j) {
totalnum[j]++;
}
}
}
for (int i = 1; i <= 7; i++) {
ArrayList<ForShow> temp = new ArrayList<>();
for (int j = 0; j < shows.size(); j++) {
if (shows.get(j).getType() == i) {
temp.add(shows.get(j));
}
}
while (temp.size() != 0) {
int s = 1000;
int g = 1000;
for (int j = 0; j < temp.size(); j++) {
if (temp.get(j).getNum() < g) {
s = j;
g = temp.get(j).getNum();
}
}
temp.get(s).getAp().show();
temp.remove(s);
}
}
整体设计的类图如下:
整体思路简述如下:
1.读取输入信息判断输入的信息种类,如果是普通串联电路将信息添加到allLine中以供并联电路选择;
2.如果为主电路则将单个元件信息添加到其中,如果为一段并联电路则根据并联电路的子电路名称在allLine中寻找添加到其中;
3.如果为控制元件的信息则进行遍历主电路查找到对应的元件并修改状态;
4.设置主电路初始电压为220,判断主电路是否联通(是否有电流通过),如果不连通则,初始化初始电压为0;
5.判断第一个元件是否为控制元件,如果是则按照其数据修改初始电压。
6.根据主电路中各个部分的电阻分配电压,并分配并联电路的各个部分电压,同时修改各个数据;
7.并将修改后的所有数据以单个元件添加到Forshow类中,输出结果
经过这三次作业的练习
1.对Java中集合,继承,多态的应用有了更深的理解以及应用技巧.
2.熟悉了更多的Java的API.
3.设计思路有了不少拓展,对问题的解决提出多样的解决方案的能力提升
4.对类的设计优化有了更深的理解,提升了设计类的巧妙性