第三單元
1. 架構設計
1.1 第一次作業
此次作業的架構比較簡單,首先依據Person
介面和JML規格來實現MyPerson
,MyPerson
類生成的每個物件都會有id
(編號)、name
(姓名)、character
(性格)、age
(年齡)、acquaintAndVaule
(認識的Person
和兩人關係的權重)和circleFlag
(所處的連通塊編號)等屬性,其中,因為id
是獨一無二,可以作為equals
的判斷依據;acquaintAndValue
用HashMap
容器實現,Person
作為key,兩人關係的權重作為value。
然後依據Network
介面和JML規格來實現MyNetwork
,其中people
Person
,用HashMap
容器實現,id
作為key,Person
作為value。在判斷兩人是否間接認識即isCircle
時,採用的是並查集演算法。每個人初始的circleFlag
是其id
,每次addRelation
時,都將其中一人的circleFlag
變成另一人的circleFlag
,基於QuickUnion實現並查集,並通過高度低的樹向高度高的數合併和路徑壓縮,就可以高效查詢網路中兩個節點的連線狀態。
1.2 第二次作業
這次作業的架構則是在上次作業的架構上作了擴充套件,首先依據Person
介面和JML規格來實現MyPerson
,和上次作業大致相同,其中MyPerson
acquaintAndValue
拆分成了acquaintance
和value
,都用HashMap
容器實現,用id
作為key,用Person
和value
分別作為value。
然後依據Group
介面和JML規格來實現MyGroup
,MyGroup
類生成的每個物件都會有id
(群組編號)、people
(群組中的人)、peopleSize
(群組中的人員數)、ageSum
(群組內所有人的年齡之和)、conflictSum
(群組內所有人的異或和)、relationSum
(群組內關係的數量之和)和valueSum
(群組內關係的權重之和)等屬性。其中,people
用HashMap
容器實現,id
作為key,Person
people
、peopleSize
、ageSum
和conflictSum
都是在addPerson
時動態維護的,relationSum
和valueSum
都是在addPerson
和addRelation
時動態維護的。
最後依據Network
介面和JML規格來實現MyNetwork
,在上次作業的基礎上增加了groups
屬性,用來記錄Network
中所有的群組,用HashMap
來實現,群組編號id
作為key,群組Group
作為value。
1.3 第三次作業
這次作業則是在上次作業的基礎上做了進一步的擴充套件。其中,MyGroup
類中增加delPerson
方法,在執行該方法時,要動態維護people
、peopleSize
、ageSum
和conflictSum
等屬性。
MyNetwork
相較於上次作業增加了很多新方法,為了更好地實現,增加了Relation
類,記錄一個Relation
中的兩個人的編號和關係權重。其中,queryMinPath
要求兩人間最短社交路徑,本次作業使用了Dijkstra演算法來實現;queryStrongLinked
要求兩人間是否有兩條不相交的社交路徑,本次作業使用了tarjan演算法來尋找點雙連通分量;queryBlockSum
要求連通塊數目,由於使用了並查集,所以不同的circleFlag
數量就是連通塊數目。
2. Bug修復情況
本單元只在第三次作業中出現3個點CTLE的情況,這三個點的特徵是大量的queryMinPath的命令。在求最短路徑時,本人採用的是Dijkstra演算法,所以重新提交後,bug修復。
3. 心得體會
第三單元的作業是JML規格下進行程式碼的實現,在具體實現時,資料的實現方式、容器的選擇、方法的實現演算法都是值得仔細考察的內容。JML規格像是簽訂了一份“契約”,在未來的工程實踐中也會十分有用。經過整個單元的學習,我對JML規格有了更深的認識,但是在工具鏈的使用和單元測試等方面還需要進一步的瞭解和學習。