本次作業是我第一次接觸jml規格,初次接觸規格帶給我的感受和第一次作業初次使用j**a以及面對電梯第一次感受多執行緒好太多太多了。理解jml語言的過程並沒有帶給我什麼煩惱,不過接觸規格之後確實讓我對我的程式設計學習有了乙個新的認識。
第一次看到規格之後我想的是,這個東西有什麼用嗎?我們明明可以用很簡潔的語言描述這些工作,明明不需要這些看起來十分繁瑣虛無縹緲的東西,為什麼一定要使用規格這樣的方式來向我們描述題目呢。等到開始實現作業**後我發現,規格這個東西是真的好用,完成作業的過程中,無論我有什麼疑問,只需要再回去看一眼規格,就能清清楚楚的明白題目的要求,完全不存在什麼講不清楚的特殊情況。通過規格這樣的方式來描述要求徹底消除了自然語言的二義性所帶來的不確定的煩惱,我們不再需要去苦苦思索或與同學深夜**出題人的這句話表達的是什麼意思,在規格中,一切都是一目了然。
不過如果讓我來自己寫規格的話,我還是很拒絕的,需要完完整整考慮到整個操作過程的一切細枝末節真的是一件很折磨的事,不過這似乎是乙個優秀程式設計師的必備素養?
不得不說,第一次作業真的是非常簡單的一次作業,可能是前三個單元所有作業裡面最簡單的一次,無論**量還是思維量都很小。第一次去嘗試實現規格中提出的要求,帶給我的感受就是我需要清清楚楚的理解規格中每個變數所表示的具體含義,規格中變數的儲存方式可能與我們自己的實現方式不同,這就需要我們保證閱讀規格的過程中把規格中的變數與我們自己打算實現的變數區分開。
作業需要實現的各個方法中最複雜的乙個就是iscircle
了,我在作業的實現過程中理所當然的想到可以再給每個人增加乙個屬性,表示所有符合iscircle
的人,ar的時候將兩個人的「高階熟人」合併,不過強測之後發現我出現了乙個很愚蠢的bug,a與b是熟人,在b與c成為熟人的時候我只讓a加到了c的熟人中,卻沒把c加到a,這導致了a與c的單向相識,就像我認識助教,而助教不認識我一樣。這個bug導致我在最後的強側中只得到了50分。
三次作業中的所有異常處理的實現都是類似的,為每個異常類增加乙個static變數對異常觸發次數進行計數。
實現iscircle
的函式確實可以在ar的時候進行預處理,但是處理的方式不應該是我使用的給每個人增加乙個高階熟人屬性,ar的過程進行合併,而是應該在network中構建關係圖,具體實現我會在後面的作業中說明。
這次作業新增了group和message類,這次作業中沒有很複雜的方法出現,send_message中有一些需要注意到的細枝末節,仔細閱讀規格就可以發現。不過由於上一次作業中,我iscircle
的實現非常愚蠢,當時雖然沒有超時,不過我還是認識到了自己的錯誤,並在第二次作業重寫了這個的實現。我使用的儲存方式是在network中構建blocks屬性,blocks是由很多block組成的,每個block中的任意兩個人都是高階熟人,也就是能找到某種方式使兩個人連起來,這樣的實現方式也給我查詢連通塊個數帶來了很大的便利。
這次我使用blocks的儲存方式,iscircle
的實現變得十分簡潔,解決了這一函式可能導致的超時問題。但是萬萬沒想到,在group中query_group_value_sum
這樣乙個不起眼的函式,我使用最簡單的遍歷來實現,它的複雜度達到了n²。最終在強測中我有乙個測試點沒通過,但是互測中被瘋狂hack。檢視cpu用時後我發現,強測中很多測試點的通過都是很極限的,只有乙個測試點沒通過真的是不幸中的萬幸。
第三次作業新增了幾個message類,我讓這幾個類繼承了mymessage
類,大多數函式的實現都還是比較簡潔的。較為複雜的乙個函式是sendmessage
,現在的sendmessage
需要對新的message類進行一些特殊處理,需要注意到jml規格中的許多細節。還有del_cold_message中我一開始沒有注意到需要刪除一些message,這也是不細心導致的問題。另外,最短路徑的計算可以說是本次作業帶來的乙個小挑戰,我使用了迪傑斯特拉演算法,最終實現了相應的功能。
在中測中,我發現cpu的時間限制從2秒變成了6秒,以為是課程組大發慈悲,不會再卡我們的時間,然而在互測中,我使用的沒有優化過的迪傑斯特拉還是被同組的人瘋狂針對,被hack4中3,強測也有乙個測試點因為cpu超時沒有通過,最終只好乖乖將最短路徑的演算法改回使用優先佇列優化過的迪傑斯特拉。
使用junit
編寫測試**對程式進行測試。junit
的配置和使用都是非常方便的,但是可能測試強度比較弱,不過可以針對不確定的方法塊進行功能測試。由於我比較懶,沒有進行過多的測試,最後也是在承受了相應的後果。
在原來使用容器的過程中我幾乎都是能用treemap
就無腦使用了treemap
,後來我聽說貌似如果不需要排序hashmap
比treemap
是要快的,於是我在後面的作業中將容器都改為了hashmap
。
person中的熟人屬性可以使用hashmap
來儲存,鍵是人,值是兩個人的value,不過有乙個需要注意的點是,如果我們只用person類作為hashmap
的鍵,是需要重寫hashcode
方法的,我在自己的**中發現了這個問題,於是改成使用人的編號作為鍵。本以為能藉此在互測中收穫一下,後來發現貌似沒有人和我一樣傻。
mynetwork
中我使用了巢狀的hashmap
來儲存blocks屬性,這方便了iscircle
方法的實現,但是這為每個人的查詢帶來了困難,所以我又單獨使用了乙個people屬性來儲存所有的人,使用的也是hashmap
儲存,鍵是person的編號,值是person。
2021 物件導向設計與構造 第三單元總結
架構上,完全照搬給出的介面,對於每乙個介面 或異常抽象類 a建立了mya將其實現 或繼承 三次作業都是這麼做的,因此不在後兩次作業中進行贅述了。絕大部分方法只需複製規格,異常類的實現使用static成員變數記錄每個id的出現次數即可。三次作業異常類大致相同,因此不在後兩次作業中進行贅述了。無向圖中新...
物件導向第三單元總結 unit3
j a建模語言 jml 是一種行為行為規範語言,可以使用給定j a模組的行為。為了支援jml語言的軸論,我們將eiffel的 合同設計 contract design 方法與larch系列框架規範語言的基於模型的規範方法相結合。主要文章為以下三篇文章。一些要素。jml是將j a程式規格化的一種表示語...
C 程式設計(物件導向高階) 第三單元測驗與作業
本題要求實現乙個swap函式,swap函式接收3個引用型別的引數,可交換3個整數a,b,c的值。將a的值存入b,b的值存入c,c的值存入a,並且返回三個整數中最大的數的值。例如a,b,c的值為1,2,3,則交換後,a,b,c的值為3,1,2,所返回的值為3。在主函式中宣告三個變數 a,b,c並賦值。...