OOP第二次blog
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.對類的設計優化有了更深的理解,提升了設計類的巧妙性

浙公網安備 33010602011771號