答題判題程式終版與家居強電電路模擬程式兩次迭代

23201533-占美斌發表於2024-06-08

目錄:
一)前言
二)設計與分析
三)踩坑心得
四)改進建議
五)總結

一.前言
(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:\s
N-\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)最後,我希望自己可以保持現在的學習狀態,甚至,更加努力,不白白浪費自己的大學時光!

相關文章