答題判題程式和傢俱強電電路模擬系統

Ccs星星远bird發表於2024-06-09

7-1 答題判題程式-4

判題系統4是對之前判題系統3的進一步引申,題目內容上增加了題目型別,變成了有選擇題和填空題,選擇題還有多選題,兩種題型的判題標準也有其特定的設定。那麼我們就這次判題系統做一次分析說明。

1.對於選擇題來說,輸入題目並沒有太多改變,而是答案的輸出有一些改變,一次輸入多個選擇,標準答案中如果包含多個正確答案(多選題),正確答案之間用英文空格分隔,這裡就意味著分割的處理要發生改變。然後是給分方式的改變,答案包含所有正確答案且不含錯誤答案給滿分;包含一個錯誤答案或完全沒有答案給0分;包含部分正確答案且不含錯誤答案給一半分,如果一半分值為小數,按截尾規則只保留整數部分,這裡在輸出的時候也需要改變輸出模式。NormalQuestion繼承自Question,而選擇題類也繼承自Question,該類有一個valid標誌、一個id、一個content和一個correctAnswers集合。然後,定義了checkAnswer方法來檢查給定的答案陣列,我們先檢查題目是否有效,如果題目無效(可能是在Question基類中定義的某個條件不滿足),則直接返回"invalid~0",再將給出的答案陣列轉換成一個HashSet集合,以便進行快速查詢和比較,如果使用者沒有給出任何答案(即給出的答案集合為空),則返回"false"然後再檢查使用者給出的答案集合是否與正確答案集合完全相等,由於HashSet比較的是元素的內容而不是順序,因此我們需要將correctAnswers也轉換為一個新的HashSet進行比較,如果給出的答案集合至少包含一個正確答案,則返回"partially correct" 否則返回"false",表示答案完全錯誤或沒有包含任何正確答案。
在這個方法中,首先會檢查題目是否有效,然後檢查使用者是否給出了答案。如果給出了答案,會先嚐試判斷答案是否完全正確(即與正確答案集合完全相等)。如果不是完全正確,會進一步檢查是否至少包含了一個正確答案。根據這些條件,方法會返回相應的字串結果("true"、"partially correct"或"false")。

2.對於填空題來說是一個道理,只是在給出答案的時候,它是填空的形式。

3.其他的類和之前幾次練習是一樣的,然後可以分析一下主函式,main方法負責呼叫兩個主要的方法:parseInput用於解析輸入,printErrorsAndResults用於列印錯誤資訊和結果。
parseInput 方法,這個方法使用一個Scanner物件來讀取標準輸入的每一行,並根據行的格式來解析題目、試卷、學生和提交資訊。如果遇到格式錯誤或不認識的格式,會將錯誤資訊新增到errors列表中。parseQuestion 方法,這個方法使用正規表示式來解析題目資訊,包括題目型別、題目內容、答案等,並將解析出的題目儲存到questions對映中,parseSubmission 方法,這個方法解析學生的提交資訊,包括試卷ID、學生ID和每個問題的答案,並將解析出的提交資訊儲存到對應學生的submissions對映中,大概整體就是這樣。

7-1傢俱強電電路模擬系統-1
在智慧家居系統中,強電電路是一個非常重要的組成部分。它負責控制和監測各種家用電器的狀態和引數,是實現智慧家居自動化的基礎。題目內容很複雜,需要一步步去分析,首先拿到這道題就知道,我們首先需要電器父類,需要分析電路,然後把電路連線起來,需要接受裝置資訊、連線資訊和控制裝置調節資訊,並輸出各個裝置的狀態或引數。

該系統的核心是各種家用電器裝置,它們被抽象為 Java 類。最基礎的是 BaseDevice 類,定義了裝置的通用屬性和方法,包括:
1.裝置型別 dt
2.裝置 ID id
3.電壓輸入pin1和pin2
4.裝置狀態status
5.檔位係數shifterVal
6.開關操作
7.電位計算getPotential()
BaseDevice 類還提供了一些受保護的方法,供子類使用,如 potentialOf() 計算輸出電壓。而基於 BaseDevice,系統定義了幾種具體的裝置類:
continuousGovernor: 連續調速器,實現了potentialOf()方法,根據輸入電壓和檔位係數計算輸出電壓。
ShiftGovernor: 分檔調速器,實現了forward()和backward()方法調節檔位,同時也實現了potentialOf() 方法。
Switch: 開關裝置,繼承自BaseDevice。
Fan: 吊扇裝置,繼承自MonitorDevice (監控裝置),實現getRotateSpeed()方法計算轉速。
FluorescentLamp: 日光燈,繼承自 Lamp (燈具),實現了 getBrightness() 方法計算亮度。
IncandescentLamp: 白熾燈,也繼承自 Lamp,實現了 getBrightness() 方法。這些裝置類的設計遵循了物件導向的原則,透過繼承和多型實現了程式碼的複用和擴充套件性。
控制裝置也需要處理。除了裝置類,該系統還需要處理裝置之間的連線和控制關係。在 Main 類的 main() 方法中,透過讀取輸入資訊,構建了三個列表,分別是baseDeviceList: 存放所有的裝置物件,connectedDeviceList: 存放串聯連線的裝置物件,controllerList: 存放可控制的裝置物件。在處理輸入資訊時,會根據不同的格式,將裝置物件新增到對應的列表中。比如以#開頭的行,表示一個控制裝置,會被新增到 controllerList。最後,系統會對這些列表進行排序和處理,輸出裝置的狀態和引數資訊。具體的邏輯如下:
1.如果controllerList不為空,且裝置數量小於baseDeviceList,則將未被控制的裝置新增到controllerList。
2.對controllerList進行排序,按裝置 ID 升序排列。
3.遍歷controllerList,根據裝置型別輸出相應的狀態或引數資訊。
4.從connectedDeviceList中移除已經輸出的裝置物件。
5.如果controllerList為空且connectedDeviceList也為空,則將 baseDeviceList 中的所有裝置輸入電壓設定為 0 和 220V。
6.如果controllerList不為空,則根據開關狀態,計算connectedDeviceList 中裝置的輸入電壓,並輸出。
這次新學到了一點關於列舉類的知識,在這裡說明一點,列舉類(Enum)在Java中是一種特殊的資料型別,它允許開發者定義一組命名的常量。列舉類是一種型別安全的方式,用於表示一組固定的值。在上述程式碼中,列舉類 DeviceTypeEnum 被用來表示裝置型別的種類,列舉類是透過enum關鍵字來定義的。在程式碼中,DeviceTypeEnum 是一個列舉類,它定義了幾種裝置型別,列舉有一些方法,比如values()返回一個包含所有列舉常量的陣列,name()返回名稱,of(String s)接受一個字串引數,並返回與該字串名稱匹配的列舉常量。如果找不到匹配的常量,它將返回null。

7-1傢俱強電電路模擬系統-2
這一次的練習加入了並聯電路,就是把串聯電路併到一起,還加入了電阻和落地燈,就要考慮電路的連線和電流,分壓等問題,前面的程式碼寫的就不太好了,所以重新開始寫了一遍,首先是類,其實類沒有多大變化,就是父類,然後繼承。我主要分析主函式的實現。主程式在使用者輸入電路配置和控制命令後,生成裝置及電路例項,並展示裝置的最終狀態。
輸入時的操作是這樣的:
List inputLines = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
// Read input lines from console until "end"
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.trim().equalsIgnoreCase("end")) {
break;
}
inputLines.add(line.trim());
}
然後我們就分析輸入,並且建立每個電器的物件並且儲存到deviceMap中去,方便後面遍歷列表。

然後private static List parseSeriesCircuits(String[] inputLines) 是處理電路,解析串聯電路:當輸入行以#T開頭時,程式碼會嘗試解析串聯電路。它透過分割冒號(:)來獲取電路ID和裝置連線字串,然後進一步分割空白字元以獲取各個連線。裝置連線解析:程式碼使用正規表示式來匹配裝置連線字串,但正規表示式可能不正確。它應該匹配裝置ID和另一個ID或數字,但目前只匹配裝置ID和後續的任何字元。構建串聯電路:如果找到有效的裝置連線,程式碼會將這些裝置新增到串聯電路的列表中,並建立一個新的 SeriesCircuit 物件。解析並聯電路:當輸入行以#M開頭時,程式碼會解析並聯電路。它獲取並聯電路的ID和包含串聯電路ID的列表,然後構建並聯電路。

applyControlCommands方法是用於應用控制命令的,它處理一系列輸入命令,根據命令型別對裝置進行操作。以下是該方法的分析:
初始化:方法開始時,將所有連續控制器(ContinuousController)的控值設定為0。
處理開關命令:如果命令以 #K 開頭,它將解析裝置識別符號,並切換該裝置的開關狀態。
處理步進控制器命令:如果命令符合 #F\d+[+-] 的模式,它將解析裝置識別符號,並根據命令尾部的+或-來增加或減少步進控制器的步數。
處理連續調檔命令:如果命令符合 #L\d+:\\d+\\.\\d{2} 的模式,它將解析裝置識別符號和控值,然後設定相應連續控制器的控值。

然後最後一部分是輸出,private static void outputDeviceStatus(List devices),先定義了一個 deviceOrder 列表,該列表指定了裝置型別的輸出順序。然後,它使用這個順序對傳入的 devices 列表進行排序。
排序規則如下:首先根據裝置型別在 deviceOrder 列表中的索引進行比較,如果裝置型別相同,則根據裝置編號進行比較,裝置編號透過呼叫 getDeviceNumber 方法獲得。
排序後,方法遍歷排序好的裝置列表,並根據裝置的實際型別輸出相應的狀態資訊。
getDeviceNumber(Device device):這個方法接收一個 Device 物件,並透過 getDeviceIdentifier 方法獲取裝置的識別符號。然後,它從識別符號中提取數字部分,將其轉換為整數並返回。getDeviceIdentifier(Device device):這個方法用於獲取裝置的識別符號。它透過遍歷 deviceMap 對映來查詢與傳入裝置物件相匹配的鍵(即識別符號)。如果找到匹配項,則返回該鍵;否則返回空字串。

然後返回一開始給主電路傳電壓,Main.mainCircuit.setInputVoltage(220);最後outputDeviceStatus(devices)輸出結果。

相關文章