一、前言
在過去的一個月中,我全身心地投入到了Javapta課程的學習中,尤其是三次極具挑戰性的大作業。這些作業不僅是對我Java程式設計技能的考驗,也是我在電腦科學領域不斷探索和成長的重要里程碑。
最近的一次大作業是關於家庭電路管理系統的開發。最初接觸這個專案時,我感到有些不知所措。這個專案要求我們運用不同的Java特性,從基本的物件導向程式設計到複雜的資料結構和演算法最佳化,以實現一個能夠模擬和管理家庭電路的應用程式。
在這個專案中,我需要設計一個系統來模擬家庭電路的各種元件,比如開關、插座、燈泡等,並實現它們之間的互動。面對這些挑戰,我逐漸意識到,學習程式設計不僅僅是掌握語法和工具,更是培養一種解決問題的思維方式。
在專案進行過程中,我不斷遇到各種技術難題和邏輯陷阱。有時候,一個小小的錯誤可能會花費數小時甚至數天去除錯和修復。然而,正是在這些反覆試錯和不斷迭代的過程中,我的程式設計能力得到了顯著提升。我學會了如何更有效地除錯程式碼,如何最佳化演算法以提高程式效率,以及如何在團隊協作中利用版本控制工具來管理專案。
此外,這個作業也讓我深刻體會到理論與實踐相結合的重要性。在課堂上學到的概念,只有透過實際編碼和專案應用,才能真正內化為自己的技能。每次成功解決一個棘手的問題,或者在專案中實現一個新功能,都會讓我感受到極大的成就感和滿足感。
在這篇部落格中,我將詳細分享這個家庭電路專案的背景、我所採用的解決方案,以及在過程中積累的經驗和教訓。我希望這些分享不僅能幫助其他正在學習Java的同學,也能為那些對程式設計充滿好奇和熱情的人提供一些有用的啟示。程式設計之路漫漫,但每一步的努力和探索都值得我們珍惜和回味。讓我們一起繼續這段充滿挑戰的學習旅程吧!
二、設計與分析
1.第四次作業7-3 答題判題程式-4
(1)難度分析:
這道題目涉及多種型別的題目處理,包括選擇題和填空題,每種題目型別都有其特定的評分規則。此外,題目還要求處理多張試卷和多名學生的答卷資訊,並根據學號和試卷號進行排序輸出。
- 題目解析與輸入處理:
需要解析不同格式的輸入資訊,包括選擇題、填空題、試卷資訊、學生資訊等。每種輸入格式都有其特定的識別符號(如#Z:、#K:、#T:等),需要正確識別並解析。
輸入資訊可能無序,因此需要在解析時做好資訊的儲存和關聯。 - 評分規則的實現:
選擇題和填空題有各自不同的評分規則,尤其是在處理多選題和部分正確的答案時,需要仔細判斷學生答卷與標準答案的匹配程度。
需要考慮部分正確答案的得分計算,並處理得分截尾的問題。 - 多張試卷和多名學生的處理:
需要正確關聯試卷資訊和學生答卷,並根據試卷的題目分值進行評分。
在輸出時,需要根據學號和試卷號進行排序,這涉及到對資料結構的選擇和排序演算法的實現。 - 輸出格式的要求:
輸出不僅包括每道題目的評分結果,還需要計算每名學生在每張試卷上的總分。
需要檢測試卷的總分是否為100分,並在不滿足時輸出相應的警告資訊。
(2)知識點分析:
- 物件導向程式設計(OOP):
抽象類和繼承:Question類是一個抽象類,定義了所有題目的基本屬性和方法。SingleChoiceQuestion、MultipleChoiceQuestion、FillInTheBlankQuestion繼承自Question,並實現了抽象方法evaluateAnswer。
封裝:類中的屬性通常是私有的,透過公共方法(getter和setter)訪問,以保護資料的完整性。
多型:透過使用抽象類和介面,允許不同的題目型別實現自己的答案評估方法。 - 集合框架:
List和Set:使用ArrayList來儲存題目、試卷、學生和答卷資訊。HashSet用於處理多選題和填空題的答案匹配。
Map:HashMap用於在答卷中儲存題號和學生答案的對應關係。 - 字串處理:
使用String.split()方法對輸入字串進行分割,以提取相關資訊。
使用trim()方法去除字串首尾的空格,確保資料的準確性。
使用正規表示式對輸入格式進行驗證和匹配。
(3)類圖和順序圖設計
(4)踩坑心得 - 填空題缺少情況
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
當答案變換順序,也應該是滿分
Set
Set
用或字分隔可以將正確答案匹配出來,無論什麼順序都可以匹配成功。
- 填空題缺少情況
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
當有一個答案是錯誤的應該0分
for (String studentAns : studentAnswers) {
for (char c : studentAns.toCharArray()) {
if (!trimmedAnswer.contains(String.valueOf(c))) {
return getContent() + "~" + studentAnswer + "~false";
}
}
}
檢查學生答案中是否有錯誤字元,有錯誤字元該題就為0分
*格式錯誤
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
S:1 20201103 #A:1-5 #A:2-A C 這個輸入無論後面有多少的空格,只需要刪除答案後面的一個空格就可以
// 判斷答案是否為空格,如果是,則刪除
if (answer.endsWith(" ")) {
answer = answer.substring(0, answer.length() - 1); // 刪除最後一個空格
}
2.第五次作業7-1 家居強電電路模擬程式-1
(1)難度分析:
- 電路模擬的複雜性
裝置多樣性:題目要求模擬多種裝置,包括開關、分檔調速器、連續調速器、白熾燈、日光燈和吊扇。每種裝置都有不同的工作特性和狀態引數,需要分別進行建模和模擬。
電路連線:需要處理裝置之間的連線資訊,確保按照正確的電路連線順序進行模擬。尤其是在處理串聯和並聯電路時,需要確保連線的正確性和完整性。
電壓和狀態計算:裝置的輸出狀態或引數(如亮度、轉速)依賴於輸入電壓或電位差,需要根據裝置的特性進行正確的計算和模擬。 - 輸入解析的複雜性
多種輸入格式:輸入資訊包括裝置資訊、連線資訊、控制裝置調節資訊等,格式各異,需要設計靈活的解析器來處理不同型別的輸入。
輸入約束:需要驗證輸入的合法性,例如確保連線資訊按照電路順序輸入,調速器的輸入端只接VCC等。 - 輸出要求的複雜性
格式化輸出:根據裝置的型別和狀態,輸出格式需要符合特定的要求,如開關的狀態顯示、連續調速器的檔位保留兩位小數等。
排序輸出:需要按裝置型別和編號順序輸出裝置狀態,這要求在輸出階段進行排序處理。 - 物件導向設計的複雜性
類設計:需要設計合理的類結構來表示各種裝置、電路連線、輸入解析和輸出處理。類之間的關係、繼承、介面設計等都需要仔細考慮。
多型和封裝:利用物件導向的多型和封裝特性,設計裝置的行為介面,以便在模擬過程中靈活呼叫不同裝置的特定行為。 - 演算法和邏輯的複雜性
狀態更新和模擬:在接收到調節資訊後,需要實時更新裝置的狀態,並重新計算受控裝置的輸出狀態。
電路模擬:在後續迭代中,隨著電路結構的複雜化(如並聯電路、巢狀電路等),需要設計更復雜的演算法來類比電路行為。
(2)知識點分析: - 抽象類與繼承
CircuitEquipment: 作為所有電路裝置的基類,包含裝置的基本屬性和方法,如裝置ID和輸出電壓。
ControlledDevice和ControlDevice: 分別繼承自CircuitEquipment,用於表示受控裝置和控制裝置,進一步擴充套件了裝置的特性,如亮度、速度和狀態。 - 多型與介面實現
各種裝置類如Switch、Dimmer、ContinuousDimmer、WhiteBulb、DaylightBulb、HairDryer等,繼承自CircuitEquipment或其子類,實現了各自的calculateOutPut方法,體現了多型的應用。 - 狀態管理
開關和調速器: 透過狀態變數(如state、level、speedRatio)和相應的方法(如toggle、increaseLevel、decreaseLevel、setSpeedRatio)來管理裝置的狀態。 - 輸入輸出處理
InPut類: 負責解析使用者輸入,建立裝置例項並新增到電路中,並根據控制指令調整裝置狀態。
OutPut類: 負責輸出裝置的當前狀態,按裝置ID排序後輸出各裝置的狀態資訊。 - 集合與排序
使用ArrayList儲存裝置,利用Collections.sort對裝置按ID排序,便於輸出時的有序處理。 - 使用者輸入解析
字串處理: 透過解析輸入字串來識別裝置連線資訊和控制命令,使用split、substring等方法提取資訊。 - 邏輯控制
使用條件語句(如if、switch)來實現對裝置狀態的判斷和相應的輸出電壓或亮度、速度的計算。 - 物件導向設計
程式碼透過物件導向的方式設計,具有良好的可擴充套件性和模組化,便於後續新增新的裝置型別或功能。
(3)類圖和順序圖設計
(4)踩坑心得及改進建議 - 開關在後面的情況
這段程式碼中實現了開關在任何地方都可以實現完整的功能
關鍵實現細節: - 裝置連線和狀態更新:
SeriesCircuit類中有一個Listdevices用於儲存電路中的所有裝置。
裝置可以按任意順序新增到電路中,並不要求開關必須在前面。 - 輸出電壓計算:
在calculateOutputs方法中,首先遍歷所有裝置,計算控制裝置(如開關、調光器)的輸出電壓。
透過Math.min函式找到所有控制裝置中的最小輸出電壓,這個最小值用於設定受控裝置(如燈泡、風扇)的電壓。
這種設計允許開關和其他控制裝置在電路中的任意位置,只要它們的狀態發生變化,就會影響到整個電路的輸出。 - 裝置狀態更新:
在InPut類中,使用者輸入的控制命令(如#K1)會觸發相應裝置的狀態更新。
呼叫toggle()方法改變開關狀態後,立即呼叫calculateOutPut()來更新輸出電壓。
緊接著,circuit.calculateOutputs()會重新計算整個電路的輸出,確保所有裝置的狀態根據最新的控制裝置狀態進行更新。
3.第六次作業7-1 家居強電電路模擬程式-2
(1)難度分析 - 程式碼結構與設計
物件導向設計:程式碼採用了物件導向的設計,定義了多個抽象類和具體類來表示不同的電路裝置。這種設計提高了程式碼的可擴充套件性和可維護性,但也增加了理解和實現的複雜性。
繼承與多型:使用繼承和多型來實現不同裝置的行為,這要求開發者對這些概念有深入的理解,尤其是在處理複雜的電路邏輯時。 - 功能實現
多種裝置型別:支援多種控制裝置(開關、分檔調速器、連續調速器)和受控裝置(白熾燈、日光燈、吊扇、落地扇),每種裝置都有不同的特性和行為。這需要為每種裝置單獨實現邏輯,並確保它們能夠正確互動。
電阻和電壓計算:引入了電阻的概念,並實現了電壓的分配和計算。需要根據電路的拓撲結構計算總電阻,並根據電阻比例分配電壓,這涉及到電路分析的基本原理。 - 演算法複雜性
電路模擬演算法:實現了串聯和並聯電路的模擬,包括電阻計算和電壓分配。這需要設計高效的演算法來處理電路的複雜拓撲結構。
輸入解析:解析複雜的輸入格式,包括裝置標識、連線資訊、控制資訊、串聯和並聯電路資訊。需要設計一個穩健的解析器來處理潛在的輸入錯誤。 - 邊緣情況
電路異常情況:需要考慮電路中可能出現的異常情況,如短路、開路等,並確保程式能夠正確處理這些情況。
輸入錯誤處理:需要設計程式來處理可能的輸入錯誤或異常情況,如格式錯誤、不合法的連線資訊等。
(2)知識點分析 - 抽象類與繼承:
CircuitEquipment 是一個抽象類,定義了電路裝置的基本特徵(如 ID、輸出電壓、電阻等)。
ControlledDevice 和 ControlDevice 繼承自 CircuitEquipment,分別代表受控裝置和控制裝置,擴充套件了特定的屬性和方法。
具體裝置類(如 Switch、Dimmer、WhiteBulb 等)繼承自上述抽象類,實現了具體的行為。 - 多型性:
抽象方法 calculateOutPut 在不同裝置類中有不同實現,體現了多型性。
透過多型性,可以在不修改程式碼的情況下擴充套件新的裝置型別。 - 封裝與資訊隱藏:
各個類透過私有屬性和公共方法封裝內部狀態,提供對外的介面。
透過方法(如 toggle、handleControl)來操作裝置狀態,隱藏了內部實現細節。 - 電路設計:
使用 SeriesCircuit 和 ParallelCircuit 類模擬串聯和並聯電路,包含裝置的連線和電阻、電壓的計算。
透過裝置的組合,實現複雜電路的模擬。 - 面向介面程式設計:
裝置的控制和狀態更新透過介面(如 calculateOutPut)進行,而不是直接操作物件,增強了程式碼的靈活性和可擴充套件性。 - 集合與資料結構:
使用 List 儲存裝置,Map 儲存裝置和電路對映,Set 用於去重和狀態跟蹤。
這些集合類的使用提高了資料管理效率和程式碼的可讀性。
(3)類圖和順序圖設計
(4)踩坑心得及改進建議 - 計算串聯電路和並聯電路的電阻
在計算串聯電阻的時候需要考慮電路里面是否有開關,如果開關是斷開狀態,則整個電路的電阻設定為0,不可以設定為無窮大,這樣會導致並聯電路的電阻計算錯誤。
在計算並聯電路的電阻時,當兩個開關都時閉合狀態而且都是閉合,就會導致短路的情況。
三、總結
在過去的幾個月中,深入學習Java程式設計的過程中,我經歷了從基礎到複雜的多個專案挑戰。這些專案不僅讓我掌握了Java的語法和特性,還培養了我解決問題的能力和程式設計思維。
透過第一次作業,我鞏固了物件導向程式設計的基礎知識,理解了類的定義、構造方法、資料封裝、常量定義和方法重寫的重要性。這為我在後續專案中設計和實現複雜的類結構奠定了基礎。
隨著作業難度的增加,我開始接觸到集合操作、字串處理和輸入輸出等中級知識點。這些技能在第二次作業中得到了充分的應用。我學會了如何有效地解析和處理輸入資料,特別是在應對格式複雜的輸入時,如何利用正規表示式和字串操作來提取有用的資訊。
第三次作業則是對我程式設計能力的全面考驗。面對多種輸入型別、複雜的資料結構設計和多樣的錯誤處理,我逐步提高了程式碼的健壯性和可維護性。我認識到,良好的程式碼結構和清晰的邏輯是解決複雜問題的關鍵。
在整個學習過程中,我也積累了許多經驗和教訓。比如,正確處理輸入中的空格和格式問題,確保程式的輸出與預期一致;在設計資料結構時,保持資料之間的關聯性和一致性;在處理錯誤時,優先處理那些對程式影響最大的錯誤。
這些專案不僅提高了我的程式設計技術,也讓我更加理解理論與實踐相結合的重要性。每次解決一個難題或實現一個新功能,都會帶給我極大的成就感和滿足感。程式設計之路充滿挑戰,但每一次努力和探索都值得珍惜。未來,我將繼續這段充滿挑戰的學習旅程,不斷提升自己的技能和知識水平。