java-BLOG-1

小瑞尔威發表於2024-10-26

1.前言
第一二個題目集除了最後一個題目以及第三個題目集的第一個題目都比較簡單,只要按照題目要求,建立相應的類,題目比較簡單一般只需要建立一個類和相應的一些屬性、方法,按照輸入輸出的要求進行建立就行。前兩個題目集只需要做對相應的輸出就能做對,而第三個題目集重點增加了對輸入的不合法的判斷,以及其對應輸出。比如:第三個題目集的第二個題目。有超過1個日期不合法和第一行日期非法、第二行日期合法且有效這兩個測試點,因為我用的是正規表示式,一開始就限定了範圍,而導致超出的範圍沒辦法判斷,所以一直通不過。後面改了正規表示式的範圍,才透過。對於這三個題目集的最後一個題目,難度大,需要建立多個類,輸入和輸出的格式和內容比較多,測試點多。

2.設計與分析
第一次題目集-答題判題程式-1
(1)類圖

  1. 類結構
    Examination:負責初始化題目數量,並儲存所有題目的判斷結果。
    Topic:處理每個題目的詳細資訊,包括正確答案、考生答案、解題過程等,並能對答案進行評判及列印。
  2. 主要功能
    初始化題目數量:透過 Examination 類的 allNumber 方法從輸入中讀取題目總數。
    讀取題目資訊:Topic 類的 answer 方法讀取每道題的詳細資訊,包括題目編號、解題過程、正確答案等。
    讀取考生答案:繼續從輸入中讀取考生的答案。
    評判答案:Topic 類的 judge 方法根據題目編號將考生答案與正確答案進行對比,並更新 Examination 類中的判斷結果。
    列印結果:Topic 類的 print 方法按題目編號排序輸出每道題的解題過程和考生答案,以及最終的判斷結果。
  3. 輸入格式
    第一行輸入題目總數。
    接下來若干行,每行包含一道題的資訊,格式為 #N:題目編號 #Q:題目內容 #A:正確答案。
    最後一行包含考生的所有答案,格式為 #A:考生答案1 #A:考生答案2 ...。
  4. 輸出格式
    按題目編號排序輸出每道題的解題過程和考生答案,中間用 ~ 分隔。
    最後一行輸出所有題目的判斷結果,用空格分隔。

部分心得:
由於第一次我還沒使用正規表示式,所以我使用的是String類裡的方法,但它有很多侷限性,必須要有固定格式而且操作繁瑣。在後面使用正規表示式,才發現正規表示式是真的方便。

input.hasNextLine() 是 Java 中 Scanner 類的一個方法,用於檢查輸入中是否還有下一行可供讀取。常用在讀取文字檔案或控制檯輸入時,通常與 input.nextLine() 方法一起使用,以確保在嘗試讀取下一行之前,輸入流中確實還有資料。

使用TreeMap有一些十分方便的方法可以輸出,不用自己格外寫函式。

第二次題目集-答題判題程式-2
(1)類圖

  1. 類結構
    Topic:處理每個題目的詳細資訊,包括正確答案、考生答案、解題過程、題號、分數等,並能對答案進行評判及列印。
    Exportation:負責驗證分數總和是否為100,並計算考生的總分。
  2. 主要功能
    讀取題目資訊:Topic 類的 answer 方法從輸入中讀取每道題的詳細資訊,包括題目編號、解題過程、正確答案、考生答案和分數。
    評判答案:Topic 類的 judge 方法將考生答案與正確答案進行對比,並儲存判斷結果。
    處理輸出:Topic 類的 process 方法按題目順序輸出每道題的解題過程、考生答案和判斷結果。
    驗證分數:Exportation 類的 validateMarks 方法驗證所有題目的分數總和是否為100。
    計算總分:Exportation 類的 getTotalMark 方法根據判斷結果計算考生的總分,並輸出每道題的得分和總分。
  3. 輸入格式
    輸入以 end 結束。
  4. 輸出格式
    按題目順序輸出每道題的解題過程、考生答案和判斷結果,格式為 題目內容考生答案判斷結果。
    輸出每道題的得分和總分,格式為 得分1 得分2 ... ~ 總分。
    如果分數總和不為100,輸出警告資訊。
    部分心得:
    這次最後一題只透過了部分測試點,成績不高,同時這個題目是在上次題目進階的,因為我上次使用的是陣列,發現陣列有侷限性,每次輸出時都要一個迴圈,而且要傳這個陣列的長度,並且要提前設定長度,這會導致有空餘。而用列表的話,它定義了很多好用的方法,不用自己再去定義函式了,省事了很多。

第三次題目集-答題判題程式-3
(1)類圖
由於這次實驗我沒有留出足夠的時間,導致我把所有功能寫在一個類裡,後面我把功能分成幾個類,並重新畫出類圖。所以這次就不多說了。

這次實驗終於使用了正規表示式,要根據輸入格式設定符合的格式。

輸入後要判斷是否符合表示式,如果符合就進行操作,由於要儲存資料,要用split來分隔資料,並進行儲存。

3.踩坑心得
(1)正規表示式的資料範圍
String regex = "^(([0-9]{4})-([0-9]{2})-(0[0-9]|[1-9][0-9]))$";
一開始正規表示式是月份和天數是固定在12和31以內的,但輸出格式是如果第一行日期字串非法,輸出自定義的錯誤資訊。所以導致輸入天數和月份超過31、12時,程式碼輸出沒反應,導致測試點沒過。
(2)計算兩日期之差

如果是自己寫個函式計算兩個日期之間的差,是比較複雜的,可以直接使用這個程式碼可以輕鬆的算出值,非常方便。
(3)檢查輸入中是否還有下一行可供讀取

如果沒有以end為結尾的要求,就需要判斷下一行是否有資料,可以考慮input.hasNextLine() 判斷下一行是否還有資料。
(4)將String型別準換成int型別
在處理String資料時常常遇到這樣的情況,要把其型別轉換成int型別,可以使用Integer.parseInt()轉換。

4.改進建議
我感覺自己的程式碼寫的不夠規範,做起題來思路也不夠寬,所以我會多多學習標準的規範的程式碼,提高自己的程式碼能力和閱讀性。
目前在以下幾個方面是可以改進的:
異常處理:增加對輸入格式的檢查,確保輸入資料的有效性。
效能最佳化:在 Topic 類的 judge 方法中,可以考慮使用雜湊表來儲存題目編號與索引的對映,以提高查詢效率。
程式碼複用:可以將一些重複的邏輯提取到單獨的方法中,如字串解析部分。

5.總結
正規表示式確實方便,一開始我都不是使用正規表示式,用了之後我就發現它得定義得知識點有很多,所以還需要深入學習。類與類之間得資料傳輸感覺把握得不是很好,常常報錯,還有就是類之間經常重複定義,明明這幾個類的作用是一樣的,可以用一個資料直接傳,而不用傳多次。同時類的定義和方法還需斟酌,定義幾個類,其屬性和方法是什麼,這是關鍵,也是最難的,需要終身學習。有時我發現使用了一鐘模式,我會依賴它,然後遇到問題時又會使用它來解決,可又是卻又不是最佳方法,可能還更繁瑣,所以需要嘗試不同的方法,瞭解其好壞和適用場景。
這幾次實驗我都沒有拿滿分,其中一個主要原因是我預留的時間不充足,所以下次實驗開始我會預留足夠的時間去寫。爭取每次都有一個好的類的結構,整體框架清晰,邏輯嚴謹。