我有一個數字串列。在我的程式中,我會經常檢查某個數字是否在我的串列中。如果它不在我的串列中,我將它添加到串列中,否則我什么也不做。我發現自己使用哈希圖而不是陣列串列來存盤專案。
void add(Map<Integer, Integer> mp, int item){
if(!mp.containsKey(item)){
mp.put(item, 1);
}
}
正如您在上面看到的,我將任何內容作為值,因為我不會使用這些值。我已經測驗過這個程序比使用陣列串列要快得多。(另外,hashmap 的 containsKey() 是 O(1),而 arraylist 的 contains() 是 O(n))
盡管它對我來說效果很好,但感覺很尷尬,原因很簡單,它不是正確的資料結構。這是一個好習慣嗎?有沒有更好的 DS 可以使用?沒有任何使用散列來存盤值的串列嗎?
uj5u.com熱心網友回復:
我有一個數字串列。在我的程式中,我會經常檢查某個數字是否在我的串列中。如果它不在我的串列中,我將它添加到串列中,否則我什么也不做。
您正在描述一個集合。從Javadoc, ajava.util.Set是:
不包含重復元素的集合。
此外,您描述的操作是add():
如果指定的元素尚不存在,則將其添加到此集合中。
在代碼中,您將創建一個新的Set(此示例使用 a HashSet):
Set<Integer> numbers = new HashSet<>();
然后,每當您遇到想要跟蹤的號碼時,只需撥打add()。如果x已經存在,則該集合將保持不變并且不會引發任何錯誤——您無需小心添加內容,只需添加您看到的任何內容,該集合會為您“過濾”出重復項。
numbers.add(x);
這超出了您最初的問題,但是一旦您填充了一個集合,您可以對資料執行各種操作 - 檢查其他數字是否存在/不存在,迭代集合中的數字等。Javadoc 顯示了哪些功能可用使用。
uj5u.com熱心網友回復:
標準庫中的另一種解決方案是java.util.BitSet. 這 - 在我看來 - 只有當 的值item不太大并且它們相對接近時才可以選擇。如果您的值彼此不接近(并且不是從零開始),那么尋找提供稀疏位集或其他稀疏資料結構的第三方解決方案可能是值得的。
您可以使用如下設定:
BitSet bits = new BitSet();
void add(int item) {
bits.set(item);
}
正如厄立特里亞評論中所建議的那樣,您也可以使用Set(例如HashSet)。在內部, aHashSet使用 a HashMap,因此它的性能類似于您當前的解決方案,但它無需將標記值放入您自己(您只需添加或洗掉專案本身)。
另外一個好處是,如果您在代碼中使用引數/欄位的型別,您可以輕松地在使用 an或 anCollection<Integer>之間切換并對其進行測驗,而無需到處更改代碼。ArrayListHashSet
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/490576.html
