oop第二次博客作業(yè)
前言
本月的學(xué)習(xí)在進(jìn)一步熟悉Java的語(yǔ)法外,還了解了程序設(shè)計(jì)的幾種模式。這三次pta主要考察的是繼承,多態(tài)的使用。部分設(shè)計(jì)模式也可使用。
學(xué)習(xí)的知識(shí)點(diǎn)
1.會(huì)使用簡(jiǎn)單的繼承與多態(tài)。
2.學(xué)習(xí)了一些重要的設(shè)計(jì)模式,對(duì)設(shè)計(jì)有了更深的認(rèn)識(shí)。
3.會(huì)使用簡(jiǎn)單的接口。
自我改進(jìn)的方面
1.對(duì)結(jié)構(gòu)的設(shè)計(jì)要考慮后面的迭代。
2.類實(shí)現(xiàn)單一職責(zé)。
設(shè)計(jì)分析
第一次PTA大作業(yè):
1)題目要求
7-1 答題判題程序-4
分?jǐn)?shù) 82
困難
作者 蔡軻
單位 南昌航空大學(xué)
設(shè)計(jì)實(shí)現(xiàn)答題程序,模擬一個(gè)小型的測(cè)試,要求輸入題目信息、試卷信息、答題信息、學(xué)生信息、刪除題目信息,根據(jù)輸入題目信息中的標(biāo)準(zhǔn)答案判斷答題的結(jié)果。本題在答題判題程序-3基礎(chǔ)上新增的內(nèi)容統(tǒng)一附加在輸出格式說(shuō)明之后,用粗體標(biāo)明。
輸入格式:
程序輸入信息分五種,信息可能會(huì)打亂順序混合輸入。
1、題目信息
題目信息為獨(dú)行輸入,一行為一道題,多道題可分多行輸入。
格式:"#N:"+題目編號(hào)+" "+"#Q:"+題目?jī)?nèi)容+" "#A:"+標(biāo)準(zhǔn)答案
格式約束:
1、題目的輸入順序與題號(hào)不相關(guān),不一定按題號(hào)順序從小到大輸入。
2、允許題目編號(hào)有缺失,例如:所有輸入的題號(hào)為1、2、5,缺少其中的3號(hào)題。此種情況視為正常。
樣例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、試卷信息
試卷信息為獨(dú)行輸入,一行為一張?jiān)嚲恚鄰埦砜煞侄嘈休斎霐?shù)據(jù)。 \
格式:"#T:"+試卷號(hào)+" "+題目編號(hào)+"-"+題目分值+" "+題目編號(hào)+"-"+題目分值+...
格式約束:
題目編號(hào)應(yīng)與題目信息中的編號(hào)對(duì)應(yīng)。
一行信息中可有多項(xiàng)題目編號(hào)與分值。
樣例:#T:1 3-5 4-8 5-2
3、學(xué)生信息
學(xué)生信息只輸入一行,一行中包括所有學(xué)生的信息,每個(gè)學(xué)生的信息包括學(xué)號(hào)和姓名,格式如下。
格式:"#X:"+學(xué)號(hào)+" "+姓名+"-"+學(xué)號(hào)+" "+姓名....+"-"+學(xué)號(hào)+" "+姓名
格式約束:
答案數(shù)量可以不等于試卷信息中題目的數(shù)量,沒(méi)有答案的題目計(jì)0分,多余的答案直接忽略,答案之間以英文空格分隔。
樣例:
#S:1 #A:5 #A:22
1是試卷號(hào)
5是1號(hào)試卷的順序第1題的題目答案
4、答卷信息
答卷信息按行輸入,每一行為一張答卷的答案,每組答案包含某個(gè)試卷信息中的題目的解題答案,答案的順序號(hào)與試 卷信息中的題目順序相對(duì)應(yīng)。答卷中:
格式:"#S:"+試卷號(hào)+" "+學(xué)號(hào)+" "+"#A:"+試卷題目的順序號(hào)+"-"+答案內(nèi)容+...
格式約束:
答案數(shù)量可以不等于試卷信息中題目的數(shù)量,沒(méi)有答案的題目計(jì)0分,多余的答案直接忽略,答案之間以英文空格分隔。
答案內(nèi)容可以為空,即””。
答案內(nèi)容中如果首尾有多余的空格,應(yīng)去除后再進(jìn)行判斷。
答卷信息中僅包含試卷號(hào)、學(xué)號(hào),而沒(méi)有后續(xù)內(nèi)容的,視為一張空白卷,為有效信息,不做格式錯(cuò)誤處理。
樣例:
#T:1 1-5 3-2 2-5 6-9 4-10 7-3
#S:1 20201103 #A:2-5 #A:6-4
1是試卷號(hào)
20201103是學(xué)號(hào)
2-5中的2是試卷中順序號(hào),5是試卷第2題的答案,即T中3-2的答案
6-4中的6是試卷中順序號(hào),4是試卷第6題的答案,即T中7-3的答案
注意:不要混淆順序號(hào)與題號(hào)
5、刪除題目信息
刪除題目信息為獨(dú)行輸入,每一行為一條刪除信息,多條刪除信息可分多行輸入。該信息用于刪除一道題目信息,題目被刪除之后,引用該題目的試卷依然有效,但被刪除的題目將以0分計(jì),同時(shí)在輸出答案時(shí),題目?jī)?nèi)容與答案改為一條失效提示,例如:”the question 2 invalid~0”
格式:"#D:N-"+題目號(hào)
格式約束:
題目號(hào)與第一項(xiàng)”題目信息”中的題號(hào)相對(duì)應(yīng),不是試卷中的題目順序號(hào)。
本題暫不考慮刪除的題號(hào)不存在的情況。
樣例:
N:1 #Q:1+1= #A:2
N:2 #Q:2+2= #A:4
T:1 1-5 2-8
X:20201103 Tom-20201104 Jack
S:1 20201103 #A:1-5 #A:2-4
D:N-2
end
輸出:
alert: full score of test paper1 is not 100 points
1+1=5false
the question 2 invalid~0
20201103 Tom: 0 0~0
答題信息以一行"end"標(biāo)記結(jié)束,"end"之后的信息忽略。
輸出格式:
1、試卷總分警示
該部分僅當(dāng)一張?jiān)嚲淼目偡址种挡坏扔?00分時(shí)作提示之用,試卷依然屬于正常試卷,可用于后面的答題。如果總分等于100 分,該部分忽略,不輸出。
格式:"alert: full score of test paper"+試卷號(hào)+" is not 100 points"
約束:有多張?jiān)嚲頃r(shí),按輸入信息的先后順序輸出警示。
樣例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行為一道題的答題信息,根據(jù)試卷的題目的數(shù)量輸出多行數(shù)據(jù)。
格式:題目?jī)?nèi)容+""+答案++""+判題結(jié)果(true/false)
約束:如果輸入的答案信息少于試卷的題目數(shù)量,每一個(gè)缺失答案的題目都要輸出"answer is null" 。
樣例:
answer is null
3+2=~5~true
4+6=~22~false.
answer is null
3、判分信息
判分信息為一行數(shù)據(jù),是一條答題記錄所對(duì)應(yīng)試卷的每道小題的計(jì)分以及總分,計(jì)分輸出的先后順序與題目題號(hào)相對(duì)應(yīng)。
格式:學(xué)號(hào)+" "+姓名+": "+題目得分+" "+....+題目得分+"~"+總分
格式約束:
1、沒(méi)有輸入答案的題目、被刪除的題目、答案錯(cuò)誤的題目計(jì)0分
2、判題信息的順序與輸入答題信息中的順序相同
樣例:20201103 Tom: 0 0~0
根據(jù)輸入的答卷的數(shù)量以上2、3項(xiàng)答卷信息與判分信息將重復(fù)輸出。
4、被刪除的題目提示信息
當(dāng)某題目被試卷引用,同時(shí)被刪除時(shí),答案中輸出提示信息。樣例見(jiàn)第5種輸入信息“刪除題目信息”。
5、題目引用錯(cuò)誤提示信息
試卷錯(cuò)誤地引用了一道不存在題號(hào)的試題,在輸出學(xué)生答案時(shí),提示”non-existent question~”加答案。例如:
輸入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103 #A:1-4
end
輸出:
alert: full score of test paper1 is not 100 points
non-existent question~0
20201103 Tom: 0~0
如果答案輸出時(shí),一道題目同時(shí)出現(xiàn)答案不存在、引用錯(cuò)誤題號(hào)、題目被刪除,只提示一種信息,答案不存在的優(yōu)先級(jí)最高,例如:
輸入:
N:1 #Q:1+1= #A:2
T:1 3-8
X:20201103 Tom-20201104 Jack-20201105 Www
S:1 20201103
end
輸出:
alert: full score of test paper1 is not 100 points
answer is null
20201103 Tom: 0~0
6、格式錯(cuò)誤提示信息
輸入信息只要不符合格式要求,均輸出”wrong format:”+信息內(nèi)容。
例如:wrong format:2 #Q:2+2= #4
7、試卷號(hào)引用錯(cuò)誤提示輸出
如果答卷信息中試卷的編號(hào)找不到,則輸出”the test paper number does not exist”,答卷中的答案不用輸出,參見(jiàn)樣例8。
8、學(xué)號(hào)引用錯(cuò)誤提示信息
如果答卷中的學(xué)號(hào)信息不在學(xué)生列表中,答案照常輸出,判分時(shí)提示錯(cuò)誤。參見(jiàn)樣例9。
本次作業(yè)新增內(nèi)容:
1、輸入選擇題題目信息
題目信息為獨(dú)行輸入,一行為一道題,多道題可分多行輸入。
格式:"#Z:"+題目編號(hào)+" "+"#Q:"+題目?jī)?nèi)容+" "#A:"+標(biāo)準(zhǔn)答案
格式基本的約束與一般的題目輸入信息一致。
新增約束:標(biāo)準(zhǔn)答案中如果包含多個(gè)正確答案(多選題),正確答案之間用英文空格分隔。
例如:
Z:2 #Q:宋代書(shū)法有蘇黃米蔡四家,分別是: #A:蘇軾 黃庭堅(jiān) 米芾 蔡襄
多選題輸出:
輸出格式與一般答卷題目的輸出一致,判斷結(jié)果除了true、false,增加一項(xiàng)”partially correct”表示部分正確。
多選題給分方式:
答案包含所有正確答案且不含錯(cuò)誤答案給滿分;包含一個(gè)錯(cuò)誤答案或完全沒(méi)有答案給0分;包含部分正確答案且不含錯(cuò)誤答案給一半分,如果一半分值為小數(shù),按截尾規(guī)則只保留整數(shù)部分。
例如:
N:1 #Q:1+1= #A:2
Z:2 #Q:黨十八大報(bào)告提出要加強(qiáng)()建設(shè)。A 政務(wù)誠(chéng)信 B 商務(wù)誠(chéng)信 C社會(huì)誠(chéng)信 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=5false
黨十八大報(bào)告提出要加強(qiáng)()建設(shè)。A 政務(wù)誠(chéng)信 B 商務(wù)誠(chéng)信 C社會(huì)誠(chéng)信 D司法公信~A C~partially correct
20201103 Tom: 0 4~4
2、輸入填空題題目信息
題目信息為獨(dú)行輸入,一行為一道題,多道題可分多行輸入。
格式:"#K:"+題目編號(hào)+" "+"#Q:"+題目?jī)?nèi)容+" "#A:"+標(biāo)準(zhǔn)答案
格式基本的約束與一般的題目輸入信息一致。
例如:#K:2 #Q:古琴在古代被稱為: #A:瑤琴或七弦琴
填空題輸出:
輸出格式與一般答卷題目的輸出一致,判斷結(jié)果除了true、false,增加一項(xiàng)”partially correct”表示部分正確。
填空題給分方式:
答案與標(biāo)準(zhǔn)答案內(nèi)容完全匹配給滿分,包含一個(gè)錯(cuò)誤字符或完全沒(méi)有答案給0分,包含部分正確答案且不含錯(cuò)誤字符給一半分,如果一半分值為小數(shù),按截尾規(guī)則只保留整數(shù)部分。
例如:
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
輸出:
alert: full score of test paper1 is not 100 points
1+1=5false
古琴在古代被稱為:瑤琴partially correct
20201103 Tom: 0 5~5
3、輸出順序變化
只要是正確格式的信息,可以以任意的先后順序輸入各類不同的信息。比如試卷可以出現(xiàn)在題目之前,刪除題目的信息可以出現(xiàn)在題目之前等。
例如:
T:1 1-5 2-10
N:1 #Q:1+1= #A:2
K:2 #Q:古琴在古代被稱為: #A:瑤琴或七弦琴
X:20201103 Tom
S:1 20201103 #A:1-5 #A:2-古箏
end
輸出:
alert: full score of test paper1 is not 100 points
1+1=5false
古琴在古代被稱為:古箏false
20201103 Tom: 0 0~0
4、多張?jiān)嚲硇畔?/p>
本題考慮多個(gè)同學(xué)有多張不同試卷的答卷的情況。輸出順序優(yōu)先級(jí)為學(xué)號(hào)、試卷號(hào),按從小到大的順序先按學(xué)號(hào)排序,再按試卷號(hào)。
例如:
T:1 1-5 2-10
T:2 1-8 2-21
N:1 #Q:1+1= #A:2
S:2 20201103 #A:1-2 #A:2-古箏
S:1 20201103 #A:1-5 #A:2-瑤琴或七弦琴
S:1 20201104 #A:1-2 #A:2-瑟
S:2 20201104 #A:1-5 #A:2-七弦琴
X:20201103 Tom-20201104 Jack
K:2 #Q:古琴在古代被稱為: #A:瑤琴或七弦琴
end
輸出:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
1+1=5false
古琴在古代被稱為:瑤琴或七弦琴true
20201103 Tom: 0 10~10
1+1=2true
古琴在古代被稱為:古箏false
20201103 Tom: 8 0~8
1+1=2true
古琴在古代被稱為:瑟false
20201104 Jack: 5 0~5
1+1=5false
古琴在古代被稱為:七弦琴partially correct
20201104 Jack: 0 10~10
新增的題目異常情況的處理與一般題目相同,具體樣例參考上一次大作業(yè)的樣例說(shuō)明:
答題判題程序-3題面.pdf
輸入樣例1:
多選題測(cè)試,不含刪除。例如:
N:1 #Q:1+1= #A:2
Z:2 #Q:黨十八大報(bào)告提出要加強(qiáng)()建設(shè)。A 政務(wù)誠(chéng)信 B 商務(wù)誠(chéng)信 C社會(huì)誠(chéng)信 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
輸出樣例1:
在這里給出相應(yīng)的輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=5false
黨十八大報(bào)告提出要加強(qiáng)()建設(shè)。A 政務(wù)誠(chéng)信 B 商務(wù)誠(chéng)信 C社會(huì)誠(chéng)信 D司法公信~A C~partially correct
20201103 Tom: 0 4~4
輸入樣例2:
填空題測(cè)試,不含刪除。例如:
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
輸出樣例2:
在這里給出相應(yīng)的輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=5false
古琴在古代被稱為:瑤琴partially correct
20201103 Tom: 0 5~5
輸入樣例3:
亂序測(cè)試,不含刪除。例如:
T:1 1-5 2-10
N:1 #Q:1+1= #A:2
K:2 #Q:古琴在古代被稱為: #A:瑤琴或七弦琴
X:20201103 Tom
S:1 20201103 #A:1-5 #A:2-古箏
end
輸出樣例3:
在這里給出相應(yīng)的輸出。例如:
alert: full score of test paper1 is not 100 points
1+1=5false
古琴在古代被稱為:古箏false
20201103 Tom: 0 0~0
輸入樣例4:
兩個(gè)同學(xué)多張不同試卷的答卷,不含刪除。例如:
T:1 1-5 2-10
T:2 1-8 2-21
N:1 #Q:1+1= #A:2
S:2 20201103 #A:1-2 #A:2-古箏
S:1 20201104 #A:1-2 #A:2-瑟
S:1 20201103 #A:1-5 #A:2-瑤琴或七弦琴
S:2 20201104 #A:1-5 #A:2-七弦琴
X:20201103 Tom-20201104 Jack
K:2 #Q:古琴在古代被稱為: #A:瑤琴或七弦琴
end
輸出樣例4:
在這里給出相應(yīng)的輸出。例如:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
1+1=5false
古琴在古代被稱為:瑤琴或七弦琴true
20201103 Tom: 0 10~10
1+1=2true
古琴在古代被稱為:古箏false
20201103 Tom: 8 0~8
1+1=2true
古琴在古代被稱為:瑟false
20201104 Jack: 5 0~5
1+1=5false
古琴在古代被稱為:七弦琴partially correct
20201104 Jack: 0 10~10
2)個(gè)人設(shè)計(jì)
本次作業(yè)的設(shè)計(jì)針對(duì)上次進(jìn)行了較大的修改
針對(duì)題目,設(shè)計(jì)了題目父類exercise
其中包含了題目編號(hào),題目?jī)?nèi)容,正確答案,是否刪除四個(gè)屬性。除構(gòu)造方法等存取類方法外,還有判斷對(duì)錯(cuò)的方法。
class exercise{
private int NO;//題目編號(hào)
private String Content;//題目?jī)?nèi)容
private String standardAnswer;//正確答案
private boolean Valid = true;//題目是否被刪除
ArrayList
public exercise(int NO, String content, String standardAnswer) {
this.NO = NO;
Content = content;
this.standardAnswer = standardAnswer;
}
public int getNO() {
return NO;
}
public void setNO(int NO) {
this.NO = NO;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
this.standardAnswer = standardAnswer;
}
//判斷對(duì)錯(cuò)
public int judge(String answer){
return -1;
}
public void disabled () {
this.Valid = false;
} //刪除題目
public void answers_Put(Answer An) {
answers.add(An);
}
public boolean getValid() {
return Valid;
}
public ArrayList<Answer> getAnswers() {
return answers;
}
public boolean isValid() {
return Valid;
}
}
對(duì)于選擇題,設(shè)計(jì)了choice_exercise類,它為exercise子類
它沒(méi)有父類之外的屬性。有用于判斷對(duì)錯(cuò)的方法 public int judge(String answer)。
class choice_exercise extends exercise {//選擇題
public choice_exercise(int NO, String content, String standardAnswer) {
super(NO, content, standardAnswer);
}
@Override
public int judge(String answer) {//-1全錯(cuò),0半錯(cuò),1全對(duì)
String StAnswer = super.getStandardAnswer().replaceAll(" ","");
String theAnswer = answer.replaceAll(" ","");
if(StAnswer.length() == theAnswer.length()) {
for(int i = 0;i < StAnswer.length() - 1;i ++) {
if(!StAnswer.contains(theAnswer.charAt(i) + "")) {
return -1;
}
}
return 1;
} else if(StAnswer.length() < theAnswer.length()) {
return -1;
} else {
for(int i = 0;i < theAnswer.length();i ++) {
if(!StAnswer.contains(theAnswer.charAt(i) + "")) {
return -1;
}
}
return 0;
}
}
}
對(duì)于填空題,設(shè)計(jì)了類gap_exercise類,它為exercise的子類。
它沒(méi)有父類之外的屬性。有用于判斷對(duì)錯(cuò)的方法 public int judge(String answer)。
class gap_exercise extends exercise {//填空題
public gap_exercise(int NO, String content, String standardAnswer) {
super(NO, content, standardAnswer);
}
@Override
public int judge(String answer) {//-1全錯(cuò),0半對(duì),1全對(duì)
if(super.getStandardAnswer().equals(answer)) {
return 1;
} else if(super.getStandardAnswer().contains(answer)) {
return 0;
} else {
return -1;
}
}
}
對(duì)于解答題,設(shè)計(jì)了free_exercise類,它為exercise的子類。
它沒(méi)有父類之外的屬性。有用于判斷對(duì)錯(cuò)的方法 public int judge(String answer)。
class free_exercise extends exercise {//解答題
public free_exercise(int NO, String content, String standardAnswer) {
super(NO, content, standardAnswer);
}
@Override
public int judge(String answer) {//只存在對(duì)錯(cuò),1對(duì)-1錯(cuò)
if(super.getStandardAnswer().equals(answer)) {
return 1;
} else {
return -1;
}
}
}
對(duì)于試卷中的題目,設(shè)計(jì)了exercise_Paper類。
它有試卷中題目順序序號(hào),試卷中題目序號(hào),題目類實(shí)例,題目分?jǐn)?shù)四個(gè)屬性。除構(gòu)造方法等存取方法外,有判斷得分的方法public int judge_markAnswer(String Answer)。
class exercise_paper {
private int thisOrder;//試卷中題目的順序號(hào),從1開(kāi)始!!!
private int thisNO;//試卷中題目的序號(hào)
private exercise thisExe;//題目類實(shí)例
private int thisScore;//題目的分?jǐn)?shù)
public exercise_paper(int thisNO,int thisOrder,int thisScore) {
this.thisNO = thisNO;
this.thisOrder = thisOrder;
this.thisScore = thisScore;
}
public int judge_markAnswer(String Answer) {//判斷得分
if(thisExe.judge(Answer) == 1) {
return thisOrder;
} else {
return 0;
}
}
public void addEXE(exercise EXE) {
this.thisExe = EXE;
}
public int getThisOrder() {
return thisOrder;
}
public int getThisNO() {
return thisNO;
}
public exercise getThisExe() {
return thisExe;
}
public int getThisScore() {
return thisScore;
}
}
針對(duì)試卷,設(shè)計(jì)了Paper類。
它有試卷編號(hào),題目數(shù)量,題目順序號(hào)與題目實(shí)例組成的HashMap,試卷總分,試卷所有題目編號(hào)的ArrayList五個(gè)屬性。只有構(gòu)造方法等存取方法。
class paper {
public static int getNoPaper() {
return NoPaper;
}
private static int NoPaper;//試卷編號(hào)
private int exerciseNum = 0;//題目數(shù)量
private HashMap<Integer, exercise_paper> SumExe;// key為題目順序號(hào),value為題目實(shí)例
private int SumGrade = 0;//試卷總分
private ArrayList<Integer> exercise_NO = new ArrayList<>();//試卷所有題目序號(hào)
public paper(int noPaper) {
NoPaper = noPaper;
SumExe = new HashMap<>(); // 初始化SumExe
}
public int getSumGrade() {
return SumGrade;
}
public void addSumGrade(int i) {
this.SumGrade = this.SumGrade + i;
}
public void SumExe_Put(int n, exercise_paper E) {
SumExe.put(n,E);
exerciseNum ++;
}
public int getExerciseNum() {
return exerciseNum;
}
public HashMap<Integer, exercise_paper> getSumExe() {
return SumExe;
}
public void addexercise_NO(int i) {
exercise_NO.add(i);
}
public ArrayList<Integer> getExercise_NO() {
return exercise_NO;
}
}
針對(duì)回答,設(shè)計(jì)了Answer類。
它有回答內(nèi)容,對(duì)錯(cuò)判斷信息,得分,答案順序號(hào),答案題目編號(hào)五個(gè)屬性。只有構(gòu)造方法等存取方法。
class Answer {
private String answer;//回答內(nèi)容
private int mark;//對(duì)判題信息
private int score = 0;//得分
private int order;//答案順序號(hào)
private int NO;//答案的題目編號(hào)
public Answer(int order, String answer) {
this.answer = answer;
this.order = order;
}
public void disable() {
}
public String getAnswer() {
return answer;
}
public int getMark() {
return mark;
}
public int getScore() {
return score;
}
public int getOrder() {
return order;
}
public int getNO() {
return NO;
}
public void setMark(int mark) {
this.mark = mark;
}
public void setScore(int score) {
this.score = score;
}
public void setNO(int NO) {
this.NO = NO;
}
}
針對(duì)答卷,設(shè)計(jì)了AnswerPaper類。
它有試卷信息,答案順序與答案實(shí)例組成的HashMap,存每題答案信息的ArrayList,存每題對(duì)錯(cuò)信息的ArrayList,答卷編號(hào),學(xué)生學(xué)號(hào),存答案順序的ArrayList七個(gè)屬性。只有存取方法。
class AnswerPaper {
private paper thispaper;//試卷信息
private HashMap<Integer,Answer> Sumanswer = new HashMap<>();//key為答卷順序,value為答卷
private ArrayList
private ArrayList
private int _NoPaper;//答卷編號(hào)
private int AnswerStuID;//學(xué)生學(xué)號(hào)
private ArrayList
public AnswerPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
}
public void addAnswer(String Answer) {
answers.add(Answer);
}
public int get_NoPaper() {
return _NoPaper;
}
public void set_NoPaper(int _NoPaper) {
this._NoPaper = _NoPaper;
}
public int getAnswerStuID() {
return AnswerStuID;
}
public void setAnswerStuID(int answerStuID) {
AnswerStuID = answerStuID;
}
public void printE_A(int num) {//輸出第num題的題目和答案,非標(biāo)準(zhǔn)答案
}
public void addSumanswer(int order,Answer An) {
Sumanswer.put(order,An);
}
public int getJudeg(int num) {//獲得第num題的對(duì)錯(cuò),num為題目順序
return Sumanswer.get(num).getMark();
}
public paper getThispaper() {
return thispaper;
}
public HashMap<Integer, Answer> getSumanswer() {
return Sumanswer;
}
public ArrayList<String> getAnswers() {
return answers;
}
public ArrayList<Integer> getMarkSum() {
return markSum;
}
public void addOrder(int i) {
Order.add(i);
}
public ArrayList<Integer> getOrder() {
return Order;
}
public void setThispaper(paper thispaper) {
this.thispaper = thispaper;
}
public void setAnswers() {//將回答存在回答列表中
for (int i = 0;i < Order.size();i ++) {
answers.add(Sumanswer.get(Order.get(i)).getAnswer());
}
}
public void setMarkSum() {
for (int i = 0;i < Order.size();i ++) {
markSum.add(Sumanswer.get(Order.get(i)).getMark());
}
}
}
針對(duì)學(xué)生,設(shè)計(jì)了student類。
它有學(xué)生號(hào),學(xué)生名字,試卷號(hào)與其對(duì)應(yīng)答卷組成的HashMap,存試卷號(hào)的ArrayList四個(gè)屬性。只有存取方法。
class student {
private int studentID;
private String name;
private HashMap<Integer,AnswerPaper> AnswerPaperOfStudent = new HashMap<>();//key為答卷的試卷號(hào)
private ArrayList
public student(int studentID, String name) {
this.studentID = studentID;
this.name = name;
}
public student() {
}
public int getStudentID() {
return studentID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void Add_APOS(int key,AnswerPaper An) {
AnswerPaperOfStudent.put(key,An);
}
public void Add_AP_O(int NO) {
AnPaper_Order.add(NO);
Collections.sort(AnPaper_Order);
}
public HashMap<Integer, AnswerPaper> getAnswerPaperOfStudent() {
return AnswerPaperOfStudent;
}
public ArrayList<Integer> getAnPaper_Order() {
return AnPaper_Order;
}
}
針對(duì)刪除的題目,設(shè)計(jì)了exerciseBeDeleted類
只有題目編號(hào)一個(gè)屬性。只有存取方法。
class student {
private int studentID;
private String name;
private HashMap<Integer,AnswerPaper> AnswerPaperOfStudent = new HashMap<>();//key為答卷的試卷號(hào)
private ArrayList
public student(int studentID, String name) {
this.studentID = studentID;
this.name = name;
}
public student() {
}
public int getStudentID() {
return studentID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void Add_APOS(int key,AnswerPaper An) {
AnswerPaperOfStudent.put(key,An);
}
public void Add_AP_O(int NO) {
AnPaper_Order.add(NO);
Collections.sort(AnPaper_Order);
}
public HashMap<Integer, AnswerPaper> getAnswerPaperOfStudent() {
return AnswerPaperOfStudent;
}
public ArrayList<Integer> getAnPaper_Order() {
return AnPaper_Order;
}
}
設(shè)計(jì)了判斷輸入有效性的類judgevalid。
只有要判斷的字符一個(gè)屬性。除存取方法外有判斷解答題輸入是否有效的方法public boolean free_exerciseValid(),判斷填空題輸入是否有效的方法public boolean gap_exerciseValid(),判斷選擇題輸入是否有效的方法public boolean choice_exerciseValid(),判斷試卷輸入是否有效的方法public boolean paperValid(),判斷學(xué)生信息輸入是否有效的方法public boolean studentValid(),判斷答卷信息輸入是否有效的方法public boolean answerPaperValid(),判斷刪除信息是否有效的方法public boolean delExeValid()。
class exerciseBeDeleted {
int delNO;
public exerciseBeDeleted(int delNO) {
this.delNO = delNO;
}
public int getDelNO() {
return delNO;
}
public void setDelNO(int delNO) {
this.delNO = delNO;
}
}
class judgevalid {
private String input;
public judgevalid(String input) {
this.input = input;
}
public String getInput() {
return input;
}
public boolean free_exerciseValid() {
String regex = "^#N:\\d+ #Q:.* #A:.*$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean gap_exerciseValid() {
String regex = "^#K:\\d+ #Q:.* #A:.*$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean choice_exerciseValid() {
String regex = "^#Z:\\d+ #Q:.* #A:.*$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean paperValid() {
String regex = "^#T:\\d+(( \\d+-\\d+)+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean studentValid() {
String regex = "^#X:((\\d+) ((\\w+)-(\\d+))+ (\\w+))";//-(\\\\d+) (\\\\w+)(?:-\\\\d+ \\\\w+)*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return true;
//return matcher.matches();
}
public boolean answerPaperValid() {
String regex = "^#S:\\d*+ \\d* +(#A:\\d*-[\\S* ]*)*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
public boolean delExeValid() {
String regex = "#D:N-\\d+$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.matches();
}
}

3)設(shè)計(jì)分析:
1.本次作業(yè)大致按照老師給出的建議進(jìn)行設(shè)計(jì)。
2.部分類的屬性出現(xiàn)的重疊,沒(méi)有進(jìn)行精簡(jiǎn)。如答卷類中每題的答案信息和對(duì)錯(cuò)信息設(shè)計(jì)多余了。
第二次PTA大作業(yè)
1)題目要求
7-1 家居強(qiáng)電電路模擬程序-1
分?jǐn)?shù) 75
作者 蔡軻
單位 南昌航空大學(xué)
智能家居是在當(dāng)下家庭中越來(lái)越流行的一種配置方案,它通過(guò)物聯(lián)網(wǎng)技術(shù)將家中的各種設(shè)備(如音視頻設(shè)備、照明系統(tǒng)、窗簾控制、空調(diào)控制、安防系統(tǒng)、數(shù)字影院系統(tǒng)、影音服務(wù)器、影柜系統(tǒng)、網(wǎng)絡(luò)家電等)連接到一起,提供家電控制、照明控制、電話遠(yuǎn)程控制、室內(nèi)外遙控、防盜報(bào)警、環(huán)境監(jiān)測(cè)、暖通控制、紅外轉(zhuǎn)發(fā)以及可編程定時(shí)控制等多種功能和手段。與普通家居相比,智能家居不僅具有傳統(tǒng)的居住功能,兼?zhèn)浣ㄖ⒕W(wǎng)絡(luò)通信、信息家電、設(shè)備自動(dòng)化,提供全方位的信息交互功能。請(qǐng)根據(jù)如下要去設(shè)計(jì)一個(gè)智能家居強(qiáng)電電路模擬系統(tǒng)。
1、控制設(shè)備模擬
本題模擬的控制設(shè)備包括:開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器。
開(kāi)關(guān):包括0和1兩種狀態(tài)。
開(kāi)關(guān)有兩個(gè)引腳,任意一個(gè)引腳都可以是輸入引腳,而另一個(gè)則是輸出引腳。開(kāi)關(guān)狀態(tài)為0時(shí),無(wú)論輸入電位是多少,輸出引腳電位為0。當(dāng)開(kāi)關(guān)狀態(tài)為1時(shí),輸出引腳電位等于輸入電位。
分檔調(diào)速器
按檔位調(diào)整,常見(jiàn)的有3檔、4檔、5檔調(diào)速器,檔位值從0檔-2(3/4)檔變化。本次迭代模擬4檔調(diào)速器,每個(gè)檔位的輸出電位分別為0、0.3、0.6、0.9倍的輸入電壓。
連續(xù)調(diào)速器
沒(méi)有固定檔位,按位置比例得到檔位參數(shù),數(shù)值范圍在[0.00-1.00]之間,含兩位小數(shù)。輸出電位為檔位參數(shù)乘以輸入電壓。
所有調(diào)速器都有兩個(gè)引腳,一個(gè)固定的輸入(引腳編號(hào)為1)、一個(gè)輸出引腳(引腳編號(hào)為2)。當(dāng)輸入電位為0時(shí),輸出引腳輸出的電位固定為0,不受各類開(kāi)關(guān)調(diào)節(jié)的影響。
所有控制設(shè)備的初始狀態(tài)/檔位為0。
控制設(shè)備的輸入引腳編號(hào)為1,輸出引腳編號(hào)為2。
2、受控設(shè)備模擬
本題模擬的受控設(shè)備包括:燈、風(fēng)扇。兩種設(shè)備都有兩根引腳,通過(guò)兩根引腳電壓的電壓差驅(qū)動(dòng)設(shè)備工作。
燈有兩種工作狀態(tài):亮、滅。在亮的狀態(tài)下,有的燈會(huì)因引腳電位差的不同亮度會(huì)有區(qū)別。
風(fēng)扇在接電后有兩種工作狀態(tài):停止、轉(zhuǎn)動(dòng)。風(fēng)扇的轉(zhuǎn)速會(huì)因引腳的電位差的不同而有區(qū)別。
本次迭代模擬兩種燈具。
白熾燈:
亮度在0~200lux(流明)之間。
電位差為0-9V時(shí)亮度為0,其他電位差按比例,電位差10V對(duì)應(yīng)50ux,220V對(duì)應(yīng)200lux,其他電位差與對(duì)應(yīng)亮度值成正比。白熾燈超過(guò)220V。
日光燈:
亮度為180lux。
只有兩種狀態(tài),電位差為0時(shí),亮度為0,電位差不為0,亮度為180。
本次迭代模擬一種吊扇。
工作電壓區(qū)間為80V-150V,對(duì)應(yīng)轉(zhuǎn)速區(qū)間為80-360轉(zhuǎn)/分鐘。80V對(duì)應(yīng)轉(zhuǎn)速為80轉(zhuǎn)/分鐘,150V對(duì)應(yīng)轉(zhuǎn)速為360轉(zhuǎn)/分鐘,超過(guò)150V轉(zhuǎn)速為360轉(zhuǎn)/分鐘(本次迭代暫不考慮電壓超標(biāo)的異常情況)。其他電壓值與轉(zhuǎn)速成正比,輸入輸出電位差小于80V時(shí)轉(zhuǎn)速為0。
輸入信息:
1、設(shè)備信息
分別用設(shè)備標(biāo)識(shí)符K、F、L、B、R、D分別表示開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器、白熾燈、日光燈、吊扇。
設(shè)備標(biāo)識(shí)用標(biāo)識(shí)符+編號(hào)表示,如K1、F3、L2等。
引腳格式:設(shè)備標(biāo)識(shí)-引腳編號(hào),例如:K1-1標(biāo)識(shí)編號(hào)為1的開(kāi)關(guān)的輸入引腳。
三種控制開(kāi)關(guān)的輸入引腳編號(hào)為1,輸出引腳編號(hào)為2。
受控設(shè)備的兩個(gè)引腳編號(hào)分別為1、2。
約束條件:
不同設(shè)備的編號(hào)可以相同。
同種設(shè)備的編號(hào)可以不連續(xù)。
設(shè)備信息不單獨(dú)輸入,包含在連接信息中。
2、連接信息
一條連接信息占一行,用[]表示一組連接在一起的設(shè)備引腳,引腳與引腳之間用英文空格" "分隔。
格式:"["+引腳號(hào)+" "+...+" "+引腳號(hào)+"]"
例如:[K1-1 K3-2 D5-1]表示K1的輸入引腳,K3的輸出引腳,D5的1號(hào)引腳連接在一起。
約束條件:
本次迭代不考慮兩個(gè)輸出引腳短接的情況
考慮調(diào)速器輸出串聯(lián)到其他控制設(shè)備(開(kāi)關(guān))的情況
不考慮調(diào)速器串聯(lián)到其他調(diào)速器的情況。
不考慮各類控制設(shè)備的并聯(lián)接入或反饋接入。例如,K1的輸出接到L2的輸入,L2的輸出再接其他設(shè)備屬于串聯(lián)接線。K1的輸出接到L2的輸出,同時(shí)K1的輸入接到L2的輸入,這種情況屬于并聯(lián)。K1的輸出接到L2的輸入,K1的輸入接到L2的輸出,屬于反饋接線。
3、控制設(shè)備調(diào)節(jié)信息
開(kāi)關(guān)調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)K+設(shè)備編號(hào),例如:#K2,代表切換K2開(kāi)關(guān)的狀態(tài)。
分檔調(diào)速器的調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)F+設(shè)備編號(hào)+"+" 代表加一檔,例如:#F3+,代表F3輸出加一檔。
+設(shè)備標(biāo)識(shí)F+設(shè)備編號(hào)+"-" 代表減一檔,例如:#F1-,代表F1輸出減一檔。
連續(xù)調(diào)速器的調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)L+設(shè)備編號(hào)+":" +數(shù)值 代表將連續(xù)調(diào)速器的檔位設(shè)置到對(duì)應(yīng)數(shù)值,例如:#L3:0.6,代表L3輸出檔位參數(shù)0.6。
4、電源接地標(biāo)識(shí):VCC,電壓220V,GND,電壓0V。沒(méi)有接線的引腳默認(rèn)接地,電壓為0V。
輸入信息以end為結(jié)束標(biāo)志,忽略end之后的輸入信息。
輸出信息:
按開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器、白熾燈、日光燈、吊扇的順序依次輸出所有設(shè)備的狀態(tài)或參數(shù)。每個(gè)設(shè)備一行。同類設(shè)備按編號(hào)順序從小到大輸出。
輸出格式:@設(shè)備標(biāo)識(shí)+設(shè)備編號(hào)+":" +設(shè)備參數(shù)值(控制開(kāi)關(guān)的檔位或狀態(tài)、燈的亮度、風(fēng)扇的轉(zhuǎn)速,只輸出值,不輸出單位)
連續(xù)調(diào)速器的檔位信息保留兩位小數(shù),即使小數(shù)為0,依然顯示兩位小數(shù).00。
開(kāi)關(guān)狀態(tài)為0(打開(kāi))時(shí)顯示turned on,狀態(tài)為1(合上)時(shí)顯示closed
如:
@K1:turned on
@B1:190
@L1:0.60
本題不考慮輸入電壓或電壓差超過(guò)220V的情況。
本題只考慮串聯(lián)的形式,所以所有測(cè)試用例的所有連接信息都只包含兩個(gè)引腳
本題電路中除了開(kāi)關(guān)可能出現(xiàn)多個(gè),其他電路設(shè)備均只出現(xiàn)一次。
電源VCC一定是第一個(gè)連接的第一項(xiàng),接地GND一定是最后一個(gè)連接的后一項(xiàng)。
家居電路模擬系列所有題目的默認(rèn)規(guī)則:
1、當(dāng)計(jì)算電壓值等數(shù)值的過(guò)程中,最終結(jié)果出現(xiàn)小數(shù)時(shí),用截尾規(guī)則去掉小數(shù)部分,只保留整數(shù)部分。為避免精度的誤差,所有有可能出現(xiàn)小數(shù)的數(shù)值用double類型保存并計(jì)算,不要作下轉(zhuǎn)型數(shù)據(jù)類型轉(zhuǎn)換,例如電壓、轉(zhuǎn)速、亮度等,只有在最后輸出時(shí)再把計(jì)算結(jié)果按截尾規(guī)則,舍棄尾數(shù),保留整數(shù)輸出。
2、所有連接信息按電路從電源到接地的順序依次輸入,不會(huì)出現(xiàn)錯(cuò)位的情況。
3、連接信息如果只包含兩個(gè)引腳,靠電源端的引腳在前,靠接地端的在后。
4、對(duì)于調(diào)速器,其輸入端只會(huì)直連VCC,不會(huì)接其他設(shè)備。整個(gè)電路中最多只有一個(gè)調(diào)速器,且連接在電源上。
家居電路模擬系列1-4題目后續(xù)迭代設(shè)計(jì):
1、電路結(jié)構(gòu)變化:
迭代1:只有一條線路,所有元件串聯(lián)
迭代2:線路中包含一個(gè)并聯(lián)電路
迭代3:線路中包含多個(gè)串聯(lián)起來(lái)的并聯(lián)電路
迭代4:并聯(lián)電路之間可能出現(xiàn)包含關(guān)系
電路結(jié)構(gòu)變化示意圖見(jiàn)圖1。
2、輸入信息的變化
串聯(lián)線路信息:用于記錄一段串聯(lián)電路的元件與連接信息。
例如: #T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
#T1:[IN K1-1] [K1-2 M1-IN][M1-OUT D2-1] [D2-2 GND]
并聯(lián)線路信息:用于記錄一段并聯(lián)電路所包含的所有串聯(lián)電路信息。
例如:#M1:[T1 T2 T3]
以上格式僅做參考,格式細(xì)節(jié)可能會(huì)調(diào)整,以具體發(fā)布的為準(zhǔn)。
3、計(jì)算方式的變化
迭代1只包含1個(gè)受控元件,不用計(jì)算電流,之后的電路計(jì)算要包含電流、電阻等電路參數(shù)。
4、電路元件的變化
每次迭代會(huì)增加1-2個(gè)新的電路元件。
image.png
圖1:電路結(jié)構(gòu)示意圖
設(shè)計(jì)建議:
1、電路設(shè)備類:描述所有電路設(shè)備的公共特征。
2、受控設(shè)備類、控制設(shè)備類:對(duì)應(yīng)受控、控制設(shè)備
3、串聯(lián)電路類:一條由多個(gè)電路設(shè)備構(gòu)成的串聯(lián)電路,也看成是一個(gè)獨(dú)立的電路設(shè)備
其他類以及類的屬性、方法自行設(shè)計(jì)。
image.png
圖2:建議設(shè)計(jì)類圖
輸入樣例1:
在這里給出一組輸入。例如:
[VCC K1-1]
[K1-2 D2-1]
[D2-2 GND]
K1
end
輸出樣例1:
在這里給出相應(yīng)的輸出。例如:
@K1:closed
@D2:360
輸入樣例2:
在這里給出一組輸入。例如:
[VCC K1-1]
[K1-2 D2-1]
[D2-2 GND]
K1
K1
end
輸出樣例2:
在這里給出相應(yīng)的輸出。例如:
@K1:turned on
@D2:0
輸入樣例3:
在這里給出一組輸入。例如:
[VCC F1-1]
[F1-2 D2-1]
[D2-2 GND]
F1+
end
輸出樣例3:
在這里給出相應(yīng)的輸出。例如:
@F1:1
@D2:0
輸入樣例4:
在這里給出一組輸入。例如:
[VCC F1-1]
[F1-2 D2-1]
[D2-2 GND]
F1+
F1+
end
輸出樣例4:
在這里給出相應(yīng)的輸出。例如:
@F1:2
@D2:288
輸入樣例5:
在這里給出一組輸入。例如:
[VCC F1-1]
[F1-2 D2-1]
[D2-2 GND]
F1+
F1+
F1+
end
輸出樣例5:
在這里給出相應(yīng)的輸出。例如:
@F1:3
@D2:360
輸入樣例6:
在這里給出一組輸入。例如:
[VCC L1-1]
[L1-2 D2-1]
[D2-2 GND]
L1:1.00
end
輸出樣例6:
在這里給出相應(yīng)的輸出。例如:
@L1:1.00
@D2:360
輸入樣例7:
在這里給出一組輸入。例如:
[VCC L1-1]
[L1-2 D2-1]
[D2-2 GND]
L1:0.68
end
輸出樣例7:
在這里給出相應(yīng)的輸出。例如:
@L1:0.68
@D2:358
輸入樣例8:
在這里給出一組輸入。例如:
[VCC L1-1]
[L1-2 B2-1]
[B2-2 GND]
L1:0.68
end
輸出樣例8:
在這里給出相應(yīng)的輸出。例如:
@L1:0.68
@B2:149
輸入樣例9:
在這里給出一組輸入。例如:
[VCC L1-1]
[L1-2 B2-1]
[B2-2 GND]
L1:1.00
end
輸出樣例9:
在這里給出相應(yīng)的輸出。例如:
@L1:1.00
@B2:200
輸入樣例10:
在這里給出一組輸入。例如:
[VCC L1-1]
[L1-2 R2-1]
[R2-2 GND]
L1:1.00
end
輸出樣例10:
在這里給出相應(yīng)的輸出。例如:
@L1:1.00
@R2:180
2)個(gè)人設(shè)計(jì)
針對(duì)全部電路設(shè)備,設(shè)計(jì)了Circuit類。
它有兩個(gè)引腳,名字三個(gè)屬性。除構(gòu)造方法與基本的存取方法外,還有展示信息的抽象方法public abstract void show()。
abstract class Circuit { //電路設(shè)備
protected int pin1 = 0;//引腳
protected int pin2 = 0;
protected String name;
public int getPin1() {
return pin1;
}
public void setPin1(int pin1) {
this.pin1 = pin1;
}
public int getPin2() {
return pin2;
}
public void setPin2(int pin2) {
this.pin2 = pin2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void show();
}
針對(duì)開(kāi)關(guān),設(shè)計(jì)了On_Off類,它為電路設(shè)備子類。
它有開(kāi)關(guān)狀態(tài)一個(gè)屬性。除構(gòu)造方法等存取方法外,還有改變開(kāi)關(guān)狀態(tài)的public void change_On_Off()方法和重寫的public void show()方法。
class On_Off extends Circuit {//開(kāi)關(guān)
private int on_off = 0;//0為關(guān)1為開(kāi)
public On_Off() {
}
public int getOn_off() {
return on_off;
}
public void setOn_off(int on_off) {
this.on_off = on_off;
}
public void change_On_Off() {
if (on_off == 0) {
on_off = 1;
} else {
on_off = 0;
}
}
@Override
public void show() {
System.out.printf("@%s:",name);
if (on_off == 0) {
System.out.printf("turned on\n");
} else {
System.out.printf("closed\n");
}
}
}
針對(duì)全部調(diào)速器,設(shè)計(jì)了Control類。
它有擋位,實(shí)際效果兩個(gè)屬性。除構(gòu)造方法等存取方法外,還有改變擋位的方法public void change_Gear(String str)。
abstract class Control extends Circuit {//調(diào)速器
protected double gear = 0;
protected double effect = 0;
public double getGear() {
return gear;
}
public void setGear(double gear) {
this.gear = gear;
}
public void change_Gear(String str) {
}
@Override
public void show() {
}
public double getEffect() {
return effect;
}
public void setEffect(double effect) {
this.effect = effect;
}
}
針對(duì)分檔調(diào)速器,設(shè)計(jì)了Step_Control類。它為Control類的子類。
它重寫的改變擋位的方法public void change_Gear(String str)。和展示的方法public void show()。
class Step_Control extends Control {//分檔調(diào)速器
@Override
public void change_Gear(String str) {
if (str.contains("+")) {
if(gear < 3) {
gear++;
effect = gear * 0.3;
}
} else if (str.contains("-")) {
if(gear > 0) {
gear--;
effect = gear * 0.3;
}
}
}
@Override
public void show() {
System.out.printf("@%s:%d\n",name,(int)gear);
}
public double getEffect() {
effect = gear * 0.3;
return effect;
}
}
針對(duì)連續(xù)調(diào)速器,設(shè)計(jì)了Continue_Control類。它為Control的子類。
它重寫了改變擋位的方法public void change_Gear(String str)和展示的方法public void show()
class Continue_Control extends Control{//連續(xù)調(diào)速器
public void changeGear(double n) {
if(n >= 0 && n <= 1) {
gear = n;
effect = gear;
}
}
@Override
public void change_Gear(String str) {
gear = Double.parseDouble(str);
effect = gear;
}
@Override
public void show() {
System.out.printf("@%s:%.2f\n",name,gear);
}
public double getEffect() {
effect = gear;
return gear;
}
}
針對(duì)受控設(shè)備,設(shè)計(jì)了Device類。它為Circuit類的子類。
它有電壓一個(gè)屬性。只有存取方法。
abstract class Device extends Circuit {//受控設(shè)備
protected double Vol;//電壓
public double getVol() {
return Vol;
}
public void setVol(double vol) {
Vol = vol;
}
}
針對(duì)電燈,設(shè)計(jì)了Light類。它為Device類的子類。
它有亮度一個(gè)屬性。只有一個(gè)獲取亮度的抽象方法public abstract double getLum()。
abstract class Light extends Device {//電燈
protected double Lum;//亮度
public abstract double getLum();
}
針對(duì)風(fēng)扇,設(shè)計(jì)了Fan類。它為Device類的子類。
它有轉(zhuǎn)速一個(gè)屬性。只有一個(gè)獲取轉(zhuǎn)速的抽象方法public abstract double getRotate()。
abstract class Fan extends Device {//風(fēng)扇
protected double rotate;//轉(zhuǎn)速
public abstract double getRotate();
}
針對(duì)白熾燈,設(shè)計(jì)了incandescent_Light類。它為L(zhǎng)ight類的子類。
它重寫了展示方法public void show()和獲取亮度的方法public double getLum()。
class incandescent_Light extends Light {//白熾燈
@Override
public void show() {
Lum = getLum();
System.out.printf("@%s:%d",name,(int)Lum);
}
@Override
public double getLum() {
if (Vol >=0 && Vol <= 9) {
Lum = 0;
return Lum;
} else if (Vol >=10 && Vol <=220) {
Lum = (50 + (150.0 / 210) * (Vol - 10));
return Lum;
} else {
return -1;
}
}
}
針對(duì)日光燈,設(shè)計(jì)了fluorescent_Light類。它為L(zhǎng)ight的子類。
它重寫了展示方法public void show()和獲取亮度的方法public double getLum()。
class fluorescent_Light extends Light {//日光燈
@Override
public void show() {
Lum = getLum();
System.out.printf("@%s:%d",name,(int)Lum);
}
@Override
public double getLum() {
if (Vol == 0) {
Lum = 0;
return Lum;
} else {
Lum = 180;
return Lum;
}
}
}
針對(duì)吊扇,設(shè)計(jì)了ceiling_Fan類。它是Fan的子類。
它重寫了獲取轉(zhuǎn)速的方法public double getRotate()和展示的方法public void show()。
class ceiling_Fan extends Fan{//吊扇
@Override
public void show() {
rotate = getRotate();
System.out.printf("@%s:%.0f",name,rotate);
}
@Override
public double getRotate() {
if (Vol >=0 && Vol < 80) {
rotate = 0;
return rotate;
} else if (Vol >= 80 && Vol <= 150) {
rotate = 80 + 280 / 70 * (Vol - 80);
return rotate;
} else {
rotate = 360;
return 360;
}
}
}
針對(duì)串聯(lián)電路,設(shè)計(jì)了Series_Circuit類。它是Circuit類的子類。
它有一個(gè)用于保存電路中全部設(shè)備的ArrayList。
class Series_Circuit extends Circuit {//串聯(lián)電路類
private ArrayList
@Override
public void show() {
}
}

3)設(shè)計(jì)分析
1.本次作業(yè)大致按照老師給出的建議進(jìn)行設(shè)計(jì)。
2.串聯(lián)電路類未使用,而是簡(jiǎn)單得將設(shè)備存在全部電路設(shè)備中。導(dǎo)致下次作業(yè)需要改動(dòng)較多內(nèi)容。
3.在輸入存儲(chǔ)數(shù)據(jù)時(shí)合理得使用了有關(guān)設(shè)計(jì)模式的知識(shí),根據(jù)不同字符串的特點(diǎn)獲得不同的數(shù)據(jù)。有效得避免了代碼的重復(fù)。
第三次PTA大作業(yè)
1)題目要求
7-1 家居強(qiáng)電電路模擬程序-2
分?jǐn)?shù) 100
作者 蔡軻
單位 南昌航空大學(xué)
智能家居是在當(dāng)下家庭中越來(lái)越流行的一種配置方案,它通過(guò)物聯(lián)網(wǎng)技術(shù)將家中的各種設(shè)備(如音視頻設(shè)備、照明系統(tǒng)、窗簾控制、空調(diào)控制、安防系統(tǒng)、數(shù)字影院系統(tǒng)、影音服務(wù)器、影柜系統(tǒng)、網(wǎng)絡(luò)家電等)連接到一起,提供家電控制、照明控制、電話遠(yuǎn)程控制、室內(nèi)外遙控、防盜報(bào)警、環(huán)境監(jiān)測(cè)、暖通控制、紅外轉(zhuǎn)發(fā)以及可編程定時(shí)控制等多種功能和手段。與普通家居相比,智能家居不僅具有傳統(tǒng)的居住功能,兼?zhèn)浣ㄖ⒕W(wǎng)絡(luò)通信、信息家電、設(shè)備自動(dòng)化,提供全方位的信息交互功能。請(qǐng)根據(jù)如下要去設(shè)計(jì)一個(gè)智能家居強(qiáng)電電路模擬系統(tǒng)。以下題目介紹中加粗的部分為本次迭代在“家居強(qiáng)電電路模擬程序-1”的基礎(chǔ)上增加的功能要求。
1、控制設(shè)備
本題模擬的控制設(shè)備包括:開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器。
開(kāi)關(guān):包括0和1兩種狀態(tài)。
開(kāi)關(guān)有兩個(gè)引腳,任意一個(gè)引腳都可以是輸入引腳,而另一個(gè)則是輸出引腳。開(kāi)關(guān)狀態(tài)為0時(shí),無(wú)論輸入電位是多少,輸出引腳電位為0。當(dāng)開(kāi)關(guān)狀態(tài)為1時(shí),輸出引腳電位等于輸入電位。
分檔調(diào)速器
按檔位調(diào)整,常見(jiàn)的有3檔、4檔、5檔調(diào)速器,檔位值從0檔-2(3/4)檔變化。本次迭代模擬4檔調(diào)速器,每個(gè)檔位的輸出電位分別為0、0.3、0.6、0.9倍的輸入電壓。
連續(xù)調(diào)速器
沒(méi)有固定檔位,按位置比例得到檔位參數(shù),數(shù)值范圍在[0.00-1.00]之間,含兩位小數(shù)。輸出電位為檔位參數(shù)乘以輸入電壓。
所有調(diào)速器都有兩個(gè)引腳,一個(gè)固定的輸入(引腳編號(hào)為1)、一個(gè)輸出引腳(引腳編號(hào)為2)。當(dāng)輸入電位為0時(shí),輸出引腳輸出的電位固定為0,不受各類開(kāi)關(guān)調(diào)節(jié)的影響。
所有控制設(shè)備的初始狀態(tài)/檔位為0。
控制設(shè)備的輸入引腳編號(hào)為1,輸出引腳編號(hào)為2。
所有開(kāi)關(guān)的電阻為 0。
2、受控設(shè)備
本題模擬的受控設(shè)備包括:燈、風(fēng)扇。兩種設(shè)備都有兩根引腳,通過(guò)兩根引腳電壓的電壓差驅(qū)動(dòng)設(shè)備工作。
燈有兩種工作狀態(tài):亮、滅。在亮的狀態(tài)下,有的燈會(huì)因引腳電位差的不同亮度會(huì)有區(qū)別。
風(fēng)扇在接電后有兩種工作狀態(tài):停止、轉(zhuǎn)動(dòng)。風(fēng)扇的轉(zhuǎn)速會(huì)因引腳間電位差的不同而有區(qū)別。
本次迭代模擬兩種燈具。
白熾燈:
亮度在0~200lux(流明)之間。
電位差為0-9V時(shí)亮度為0,其他電位差按比例,電位差10V對(duì)應(yīng)50ux,220V對(duì)應(yīng)200lux,其他電位差與對(duì)應(yīng)亮度值成正比。白熾燈超過(guò)220V。
日光燈:
亮度為180lux。
只有兩種狀態(tài),電位差為0時(shí),亮度為0,電位差不為0,亮度為180。
本次迭代模擬一種吊扇。
工作電壓區(qū)間為80V-150V,對(duì)應(yīng)轉(zhuǎn)速區(qū)間為80-360轉(zhuǎn)/分鐘。80V對(duì)應(yīng)轉(zhuǎn)速為80轉(zhuǎn)/分鐘,150V對(duì)應(yīng)轉(zhuǎn)速為360轉(zhuǎn)/分鐘,超過(guò)150V轉(zhuǎn)速為360轉(zhuǎn)/分鐘(本次迭代暫不考慮電壓超標(biāo)的異常情況)。其他電壓值與轉(zhuǎn)速成正比,輸入輸出電位差小于80V時(shí)轉(zhuǎn)速為0。
本次迭代模擬一種落地扇。
工作電壓區(qū)間為 [80V,150V],對(duì)應(yīng)轉(zhuǎn)速區(qū)間為 80-360 轉(zhuǎn)/分鐘。電壓在[80,100)V 區(qū)間對(duì)應(yīng)轉(zhuǎn)速為 80 轉(zhuǎn)/分 鐘,[100-120)V 區(qū)間對(duì)應(yīng)轉(zhuǎn)速為 160 轉(zhuǎn)/分鐘,[120-140)V 區(qū)間對(duì)應(yīng)轉(zhuǎn)速為 260 轉(zhuǎn)/分鐘,超過(guò) 140V 轉(zhuǎn)速 為 360 轉(zhuǎn)/分鐘(本次迭代暫不考慮電壓超標(biāo)的異常情況)輸入信息:
本次迭代考慮電阻:白熾燈的電阻為 10,日光燈的電阻為 5,吊扇的電阻為 20,落 地扇的電阻為 20
3、輸入信息
1)輸入設(shè)備信息
分別用設(shè)備標(biāo)識(shí)符K、F、L、B、R、D、A分別表示開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器、白熾燈、日光燈、吊扇、落地扇。
設(shè)備標(biāo)識(shí)用標(biāo)識(shí)符+編號(hào)表示,如K1、F3、L2等。
引腳格式:設(shè)備標(biāo)識(shí)-引腳編號(hào),例如:K1-1標(biāo)識(shí)編號(hào)為1的開(kāi)關(guān)的輸入引腳。
三種控制開(kāi)關(guān)的輸入引腳編號(hào)為1,輸出引腳編號(hào)為2。
受控設(shè)備的兩個(gè)引腳編號(hào)分別為1、2。
約束條件:
不同設(shè)備的編號(hào)可以相同。
同種設(shè)備的編號(hào)可以不連續(xù)。
設(shè)備信息不單獨(dú)輸入,包含在連接信息中。
2)輸入連接信息
一條連接信息占一行,用[]表示一組連接在一起的設(shè)備引腳,引腳與引腳之間用英文空格" "分隔。
格式:"["+引腳號(hào)+" "+...+" "+引腳號(hào)+"]"
例如:[K1-1 K3-2 D5-1]表示K1的輸入引腳,K3的輸出引腳,D5的1號(hào)引腳連接在一起。
約束條件:
不考慮調(diào)速器串聯(lián)到其他調(diào)速器的情況。
不考慮調(diào)速器串聯(lián)到其他調(diào)速器的情況。
考慮各類設(shè)備的并聯(lián)接入。例如,K1 的輸出接到 L2 的輸入,L2 的輸出再接其他設(shè)備屬于串聯(lián)接線。K1 的輸出接到 L2 的輸出,同時(shí) K1 的輸入接到 L2 的輸入,這種情況屬于并聯(lián)。
本次迭代的連接信息不單獨(dú)輸入,包含在線路信息中。
3)輸入控制設(shè)備調(diào)節(jié)信息
開(kāi)關(guān)調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)K+設(shè)備編號(hào),例如:#K2,代表切換K2開(kāi)關(guān)的狀態(tài)。
分檔調(diào)速器的調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)F+設(shè)備編號(hào)+"+" 代表加一檔,例如:#F3+,代表F3輸出加一檔。
+設(shè)備標(biāo)識(shí)F+設(shè)備編號(hào)+"-" 代表減一檔,例如:#F1-,代表F1輸出減一檔。
連續(xù)調(diào)速器的調(diào)節(jié)信息格式:
+設(shè)備標(biāo)識(shí)L+設(shè)備編號(hào)+":" +數(shù)值 代表將連續(xù)調(diào)速器的檔位設(shè)置到對(duì)應(yīng)數(shù)值,例如:#L3:0.6,代表L3輸出檔位參數(shù)0.6。
4)電源接地標(biāo)識(shí):
VCC,電壓220V,GND,電壓0V。沒(méi)有接線的引腳默認(rèn)接地,電壓為0V。
5)輸入串聯(lián)電路信息
一條串聯(lián)電路占一行,串聯(lián)電路由按從靠電源端到接地端順序依次輸入的 n 個(gè)連接 信息組成,連接信息之間用英文空格" "分隔。
串聯(lián)電路信息格式:
"#T"+電路編號(hào)+":"+連接信息+" "+連接信息+...+" "+連接信息
例如:#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT] 一個(gè)串聯(lián)電路的第一個(gè)引腳是 IN,代表起始端,靠電源。最后一個(gè)引腳是 OUT,代表結(jié)尾端, 靠接地。
約束條件:
不同的串聯(lián)電路信息編號(hào)不同。
輸入的最后一條電路信息必定是總電路信息,總電路信息的起始引腳是 VCC,結(jié)束引腳是 GND。
連接信息中的引腳可能是一條串聯(lián)或并聯(lián)電路的 IN 或者 OUT。例如:
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT OUT]
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT M2-IN] [M2-OUT OUT]
6)輸入并聯(lián)電路信息
一條并聯(lián)電路占一行,并聯(lián)電路由其包含的幾條串聯(lián)電路組成,串聯(lián)電路標(biāo)識(shí)之間用英文空格" "分隔。
格式:
"#M"+電路編號(hào)+":"+”[”+串聯(lián)電路信息+" "+....+" "+串聯(lián)電路信息+”]”
例如:#M1:[T1 T2 T3]
該例聲明了一個(gè)并聯(lián)電路,由 T1、T2、T3 三條串聯(lián)電路并聯(lián)而成,三條串聯(lián)電路的 IN 短 接在一起構(gòu)成 M1 的 IN,三條串聯(lián)電路的 OUT 短接在一起構(gòu)成 M1 的 OUT。
約束條件:
本次迭代不考慮并聯(lián)電路中包含并聯(lián)電路的情況,也不考慮多個(gè)并聯(lián)電路串聯(lián)的情況。
本題不考慮輸入電壓或電壓差超過(guò)220V的情況。
輸入信息以end為結(jié)束標(biāo)志,忽略end之后的輸入信息。
本題中的并聯(lián)信息所包含的串聯(lián)電路的信息都在并聯(lián)信息之前輸入,不考慮亂序輸入的情況。
電路中的短路如果不會(huì)在電路中產(chǎn)生無(wú)窮大的電流燒壞電路,都是合理情況,在本題測(cè)試點(diǎn)的考慮范圍之內(nèi)。
本題不考慮一條串聯(lián)電路中包含其他串聯(lián)電路的情況。例如:
T3:[VCC K1-1] [K1-2 T2-IN] [T2-OUT K2-1] [K2-2 T1-IN] [T1-OUT GND]
本例中T1\T2兩條串聯(lián)電路實(shí)際是T3的一個(gè)部分,本題不考慮這種類型的輸入,而是當(dāng)將T1\T2的所有連接信息直接包含在T3中定義。
下次迭代中需要考慮這種類型的輸入。
4、輸出信息:
按開(kāi)關(guān)、分檔調(diào)速器、連續(xù)調(diào)速器、白熾燈、日光燈、吊扇、落地扇的順序依次輸出所有設(shè)備的狀態(tài)或參數(shù)。每個(gè)設(shè)備一行。同類設(shè)備按編號(hào)順序從小到大輸出。
輸出格式:@設(shè)備標(biāo)識(shí)+設(shè)備編號(hào)+":" +設(shè)備參數(shù)值(控制開(kāi)關(guān)的檔位或狀態(tài)、燈的亮度、風(fēng)扇的轉(zhuǎn)速,只輸出值,不輸出單位)
連續(xù)調(diào)速器的檔位信息保留兩位小數(shù),即使小數(shù)為0,依然顯示兩位小數(shù).00。
開(kāi)關(guān)狀態(tài)為0(打開(kāi))時(shí)顯示turned on,狀態(tài)為1(合上)時(shí)顯示closed
如:
@K1:turned on
@B1:190
@L1:0.60
5、家居電路模擬系列所有題目的默認(rèn)規(guī)則:
1)當(dāng)計(jì)算電壓值等數(shù)值的過(guò)程中,最終結(jié)果出現(xiàn)小數(shù)時(shí),用截尾規(guī)則去掉小數(shù)部分,只保留整數(shù)部分。為避免精度的誤差,所有有可能出現(xiàn)小數(shù)的數(shù)值用double類型保存并計(jì)算,不要作下轉(zhuǎn)型數(shù)據(jù)類型轉(zhuǎn)換,例如電壓、轉(zhuǎn)速、亮度等,只有在最后輸出時(shí)再把計(jì)算結(jié)果按截尾規(guī)則,舍棄尾數(shù),保留整數(shù)輸出。
2)所有連接信息按電路從電源到接地的順序依次輸入,不會(huì)出現(xiàn)錯(cuò)位的情況。電源VCC一定是第一個(gè)連接的第一項(xiàng),接地GND一定是最后一個(gè)連接的后一項(xiàng)。
3)連接信息如果只包含兩個(gè)引腳,靠電源端的引腳在前,靠接地端的在后。
4)調(diào)速器的輸入端只會(huì)直連VCC,不會(huì)接其他設(shè)備。整個(gè)電路最多只有連接在電源上的一個(gè)調(diào)速器,且不包含在并聯(lián)單路中。
6、家居電路模擬系列1-4題目后續(xù)迭代設(shè)計(jì):
1)電路結(jié)構(gòu)變化:
迭代1:只有一條線路,所有元件串聯(lián)
迭代2:線路中包含一個(gè)并聯(lián)電路
迭代3:線路中包含多個(gè)串聯(lián)起來(lái)的并聯(lián)電路
迭代4:并聯(lián)電路之間可能出現(xiàn)包含關(guān)系
電路結(jié)構(gòu)變化示意圖見(jiàn)圖1。
2)計(jì)算方式的變化
迭代1只包含1個(gè)受控元件,不用計(jì)算電流,之后的電路計(jì)算要包含電流、電阻等電路參數(shù)。
3)電路元件的變化
每次迭代會(huì)增加1-2個(gè)新的電路元件。
image.png
圖1:電路結(jié)構(gòu)示意圖
設(shè)計(jì)建議:
1、電路設(shè)備類:描述所有電路設(shè)備的公共特征。
2、受控設(shè)備類、控制設(shè)備類:對(duì)應(yīng)受控、控制設(shè)備
3、串聯(lián)電路類:一條由多個(gè)電路設(shè)備構(gòu)成的串聯(lián)電路,也看成是一個(gè)獨(dú)立的電路設(shè)備
4、并聯(lián)電路類:繼承電路設(shè)備類,也看成是一個(gè)獨(dú)立的電路設(shè)備
其他類以及類的屬性、方法自行設(shè)計(jì)。
image.png
圖2:建議設(shè)計(jì)類圖
輸入格式:
請(qǐng)?jiān)谶@里寫輸入格式。例如:輸入在一行中給出2個(gè)絕對(duì)值不超過(guò)1000的整數(shù)A和B。
輸出格式:
請(qǐng)?jiān)谶@里描述輸出格式。例如:對(duì)每一組輸入,在一行中輸出A+B的值。
輸入樣例1:
在這里給出一組輸入。例如:
T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
M1:[T1 T2]
T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
K1
end
輸出樣例1:
在這里給出相應(yīng)的輸出。例如:
@K1:closed
@K2:turned on
@L1:0.00
@D1:0
@D2:0
@D3:0
輸入樣例2:
在這里給出一組輸入。例如:
T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
M1:[T1 T2]
T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
K1
L1:1.00
end
輸出樣例2:
在這里給出相應(yīng)的輸出。例如:
@K1:closed
@K2:turned on
@L1:1.00
@D1:0
@D2:200
@D3:200
輸入樣例3:
在這里給出一組輸入。例如:
T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
M1:[T1 T2]
T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
K1
K2
L1:1.00
end
輸出樣例3:
在這里給出相應(yīng)的輸出。例如:
@K1:closed
@K2:closed
@L1:1.00
@D1:0
@D2:0
@D3:346
2)個(gè)人設(shè)計(jì)
在電路設(shè)備中新增電阻,電壓兩個(gè)屬性。
abstract class Circuit { //電路設(shè)備
protected int pin1 = 0;//引腳
protected int pin2 = 0;
protected String name;
protected double resistance;//電阻
protected double Vol;
public int getPin1() {
return pin1;
}
public void setPin1(int pin1) {
this.pin1 = pin1;
}
public int getPin2() {
return pin2;
}
public void setPin2(int pin2) {
this.pin2 = pin2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void show();
public double getResistance() {
return resistance;
}
public void setResistance(double resistance) {
this.resistance = resistance;
}
public double getVol() {
return Vol;
}
public void setVol(double vol) {
Vol = vol;
}
}
為更好分辯,將分檔調(diào)速器重命名為F_Control,連續(xù)調(diào)速器重命名為L(zhǎng)_Control,白熾燈重命名為B_Light,日光燈重命名為R_Light,串聯(lián)電路重命名為T_Circuit,吊扇重命名為D_Fan。
由于電路設(shè)備中存在電壓屬性,自然要去除受控設(shè)備中的電壓屬性。
abstract class Device extends Circuit {//受控設(shè)備
public double getVol() {
return Vol;
}
public void setVol(double vol) {
Vol = vol;
}
}
各電路設(shè)備新增電阻屬性和獲得編號(hào)的方法。
class B_Light extends Light {//白熾燈
public B_Light() {
resistance = 10;
}
@Override
public void show() {
Lum = getLum();
System.out.printf("@%s:%d\n",name,(int)Lum);
}
@Override
public double getLum() {
if (Vol >=0 && Vol <= 9) {
Lum = 0;
return Lum;
} else if (Vol >=10 && Vol <=220) {
Lum = (50 + (150.0 / 210) * (Vol - 10));
return Lum;
} else {
return -1;
}
}
public int getNO() {
return Integer.parseInt(name.replace("B",""));
}
}
class R_Light extends Light {//日光燈
public R_Light() {
resistance = 5;
}
@Override
public void show() {
Lum = getLum();
System.out.printf("@%s:%d\n",name,(int)Lum);
}
@Override
public double getLum() {
if (Vol == 0) {
Lum = 0;
return Lum;
} else {
Lum = 180;
return Lum;
}
}
public int getNO() {
return Integer.parseInt(name.replace("R",""));
}
}
class D_Fan extends Fan{//吊扇
public D_Fan() {
resistance = 20;
}
@Override
public void show() {
rotate = getRotate();
System.out.printf("@%s:%d\n",name,(int)(rotate));
}
@Override
public double getRotate() {
if (Vol >=0 && Vol < 80) {
rotate = 0;
} else if (Vol >= 80 && Vol <= 150) {
rotate = 80 + 280 / 70 * (Vol - 80);
} else {
rotate = 360;
}
return rotate;
}
public int getNO() {
return Integer.parseInt(name.replace("D",""));
}
}
新增落地扇類。
class A_Fan extends Fan {//落地扇
public A_Fan() {
resistance = 20;
}
@Override
public void show() {
rotate = getRotate();
System.out.printf("@%s:%d\n",name,(int)rotate);
}
@Override
public double getRotate() {
if (Vol >=80 && Vol <=99) {
rotate = 80;
} else if (Vol >= 100 && Vol <=119) {
rotate = 160;
} else if (Vol >= 120 && Vol <=139) {
rotate = 260;
} else if (Vol >= 140 && Vol <=150) {
rotate = 360;
} else {
rotate = 0;
}
return rotate;
}
public int getNO() {
return Integer.parseInt(name.replace("A",""));
}
}
新增電路類Circuit_Line。它為Circuit的子類。
它有記錄電路設(shè)備的ArrayList一個(gè)屬性和判斷電路是否通路的方法。
class Circuit_Line extends Circuit{//串聯(lián)父類
protected ArrayList
public ArrayList
return CircuitList;
}
@Override
public void show() {
}
public int Access() {
for (int i = 0;i < CircuitList.size();i ++) {
if (CircuitList.get(i) instanceof On_Off) {
if (((On_Off) CircuitList.get(i)).getOn_off() == 0) {
return -1;
}
}
}
return 0;
}
}
串聯(lián)電路類更改為電路類的子類,新增分配電壓的方法public void Cal_V()和獲得總電阻的方法public double getResistance()。
class T_Circuit extends Circuit_Line {//串聯(lián)電路類
@Override
public void show() {
}
public void addCircuit(Circuit c) {
CircuitList.add(c);
}
@Override
public double getResistance() {
double r = 0;
for (int i = 0; i < CircuitList.size(); i++) {
r = r + CircuitList.get(i).getResistance();
}
resistance = r;
return resistance;
}
public void Cal_V() {
if (this.Access() != -1) {
double r = 0;//總電阻
for (int i = 0; i < CircuitList.size(); i++) {
r = r + CircuitList.get(i).getResistance();
}
for (int i = 0; i < CircuitList.size(); i++) {
double V = Vol / r * CircuitList.get(i).getResistance();
CircuitList.get(i).setVol(V);
}
} else {
for (int i = 0;i < CircuitList.size();i ++) {
CircuitList.get(i).setVol(0);
}
}
}
}
新增并聯(lián)電路類,它為Circuit_Line的子類。
它屬性和方法與串聯(lián)電路類相似。
class M_Circuit extends Circuit_Line {
@Override
public void show() {
}
public void addCircuit(Circuit c) {
CircuitList.add(c);
}
@Override
public int Access() {//并聯(lián)是否正常
int count = 0;
for (int i = 0 ;i < CircuitList.size();i ++) {
if (((T_Circuit)CircuitList.get(i)).Access() != -1) {
count++;
}
}
if (count == 0) {
return -1;//斷路
} else if (count == CircuitList.size()) {
return 0;//正常并聯(lián)
} else {
return 1;//單連接
}
}
@Override
public double getResistance() {
if (this.Access() != -1) {
double r = 0;
for (int i = 0; i < CircuitList.size(); i++) {
r = 1.0 / CircuitList.get(i).getResistance() + r;
}
resistance = 1.0 / r;
} else {
for (int i = 0;i < CircuitList.size();i++) {
if (((T_Circuit)CircuitList.get(i)).Access() != -1) {
resistance = CircuitList.get(i).getResistance();
}
}
}
return resistance;
}
public void Cal_V() {
if (this.Access() != -1) {
for (int i = 0; i < CircuitList.size(); i++) {
CircuitList.get(i).setVol(Vol);
}
} else {
for (int i = 0;i < CircuitList.size();i ++) {
if (((T_Circuit)CircuitList.get(i)).Access() != -1) {
CircuitList.get(i).setVol(Vol);
}
}
}
}
}
新增總電路類,它為Circuit_Line的子類。
它只有簡(jiǎn)單的存取方法。
class Line extends Circuit_Line{
public void addCircuit(Circuit c) {
for (int i = 0;i < CircuitList.size();i ++) {
for (int j = 0; j < ((Circuit_Line) c).getCircuitList().size(); j ++) {
if (CircuitList.size() >= 1) {
if (CircuitList.get(i).equals(((Circuit_Line) c).getCircuitList().get(j))) {
CircuitList.remove(i);
}
}
}
}
CircuitList.add(c);
}
public void Cal_V(double effect) {//計(jì)算電壓
double r = 0;//總電阻
for (int i = 0 ;i < CircuitList.size();i ++) {
r = r + CircuitList.get(i).getResistance();
}
for (int i = 0;i < CircuitList.size();i ++) {
double V = effect * 220 / r * CircuitList.get(i).getResistance();
CircuitList.get(i).setVol(V);
}
}
public ArrayList<Circuit> getCircuitList() {
return CircuitList;
}
}

3)設(shè)計(jì)分析
1.在上次作業(yè)基礎(chǔ)上進(jìn)行了較大更改,結(jié)構(gòu)更合理的同時(shí)也更好分辨。
2.Main類中存有大量數(shù)據(jù),未合理使用設(shè)計(jì)模式進(jìn)行處理。
踩坑心得
1.第二次作業(yè)依舊沒(méi)有對(duì)結(jié)構(gòu)進(jìn)行很好的設(shè)計(jì)。未意識(shí)到串并聯(lián)電路也可以視作單個(gè)用電器。日后需要注意。
2.應(yīng)該合理得使用設(shè)計(jì)模式。三次大作業(yè)的數(shù)據(jù)都直接寫在Main中,過(guò)于冗長(zhǎng)。
改進(jìn)建議
1.新建數(shù)據(jù)類用于存儲(chǔ)數(shù)據(jù)。以下內(nèi)容不要寫在Main里。
public static ArrayList<Circuit> Sum_Circuit = new ArrayList<>();//電路設(shè)備(全部的設(shè)備)
public static HashMap<String,Circuit> Sum_CircuitMap = new HashMap<>();//電路設(shè)備
public static ArrayList<T_Circuit> t_CircuitList = new ArrayList<>();//串聯(lián)電路
public static HashMap<String,Circuit> Series_CircuitMap = new HashMap<>();
public static ArrayList<M_Circuit> m_CircuitList = new ArrayList<>();//并聯(lián)電路
public static HashMap<String,Circuit> Multiple_CircuitMap = new HashMap<>();
public static HashMap<Integer, On_Off> On_OffMap = new HashMap<>();//開(kāi)關(guān)
public static ArrayList<On_Off> On_OffList = new ArrayList<>();//開(kāi)關(guān)
public static Control control = null;//控制設(shè)備(調(diào)速器)
public static ArrayList<Device> DeviceList = new ArrayList<>();//受控設(shè)備(用電器)
public static HashMap<String,Device> DeviceMap = new HashMap<>();//受控設(shè)備
public static HashMap<Integer, B_Light> B_LightMap = new HashMap<>();//白熾燈
public static HashMap<Integer,R_Light> R_LightMap = new HashMap<>();//日光燈
public static HashMap<Integer,D_Fan> D_FanMap = new HashMap<>();//吊扇
public static HashMap<Integer,A_Fan> A_FanMap = new HashMap<>();//落地扇
public static ArrayList<B_Light> B_LightList = new ArrayList<>();
public static ArrayList<R_Light> R_LightList = new ArrayList<>();
public static ArrayList<D_Fan> D_FanList = new ArrayList<>();
public static ArrayList<A_Fan> A_FanList = new ArrayList<>();
public static Line Line_Circuit = new Line();
2.以下部分可以寫成方法
while (!Str.equals("end")) {
//串聯(lián)電路
if (Str.contains("#T")) {
String parts[] = Str.split("\] \[| |:\[");
String name = parts[0].replace("#","");
T_Circuit s_c = new T_Circuit();
s_c.setName(name);
for (int i = 2;i < parts.length - 1;i = i + 2) {
if (parts[i].contains("M")) {
String part[] = parts[i].split("-");
s_c.addCircuit(Multiple_CircuitMap.get(part[0]));
} else if (parts[i].contains("T")) {
String part[] = parts[i].split("-");
s_c.addCircuit(Series_CircuitMap.get(part[0]));
} else if (!parts[i].contains("T") || parts[i].contains("M")) {
Save(parts[i], s_c);
}
}
t_CircuitList.add(s_c);
Series_CircuitMap.put(name,s_c);
Line_Circuit.addCircuit(s_c);
//并聯(lián)電路
} else if (Str.contains("#M")) {
String parts[] = Str.split("\\[|\\]| |:");
String name = parts[0].replace("#","");
M_Circuit m_c = new M_Circuit();
m_c.setName(name);
for (int i = 2;i < parts.length;i ++) {
m_c.addCircuit(Series_CircuitMap.get(parts[i]));
}
m_CircuitList.add(m_c);
Multiple_CircuitMap.put(name,m_c);
Line_Circuit.addCircuit(m_c);
//控制開(kāi)關(guān)
} else if (Str.contains("#K")) {
int NO = Integer.parseInt(Str.replace("#K",""));
String name = Str.replace("#","");
On_OffMap.get(NO).change_On_Off();
//控制分檔調(diào)速器
} else if (Str.contains("#F")) {
String name = Str.replace("#","").replace("+","");
control.change_Gear(Str);
//控制連續(xù)調(diào)速器
} else if (Str.contains("#L")) {
String parts[] = Str.split(":");
String name = parts[0].replace("#","");
control.change_Gear(parts[1]);
}
Str = sc.nextLine();
}
浙公網(wǎng)安備 33010602011771號(hào)