如何使用 C 中的 HashSet

2021-10-12 13:00:01 字數 4385 閱讀 2862

hashset 是乙個優化過的無序集合,提供對元素的高速查詢和高效能的set集合操作,而且 hashset 是在 .net 3.5 中被引入的,在system.collection.generic命名空間下,這篇就來討論一下如何使用這個 hashset。

所謂的hashset,指的就是system.collections.generic命名空間下的hashset類,它是乙個高效能,無序的集合,因此hashset它並不能做排序操作,也不能包含任何重複的元素,hashset 也不能像陣列那樣使用索引,所以在 hashset 上你無法使用 for 迴圈,只能使用 foreach 進行迭代,hashset 通常用在處理元素的唯一性上有著超高的效能。

hashset實現了如下幾個介面:

public class hashset: system.collections.generic.icollection,

system.collections.generic.ienumerable,

system.collections.generic.ireadonlycollection,

system.collections.generic.iset,

system.runtime.serialization.ideserializationcallback,

system.runtime.serialization.iserializable

hashset 只能包含唯一的元素,它的內部結構也為此做了專門的優化,值得注意的是,hashset 也可以存放單個的 null 值,可以得出這麼乙個結論:如何你想擁有乙個具有唯一值的集合,那麼 hashset 就是你最好的選擇,何況它還具有超高的檢索效能。

如果想判斷某乙個元素是否在 hashset 內,建議使用 contains 進行判斷,**如下:

static void main(string args)

如果你向 hashset 中插入重複的元素,它的內部會忽視這次操作而不像別的集合一樣丟擲異常,接下來展示一下**:

static void main(string args)

", hashset.count);

console.readkey();

}

當你執行了這個程式,輸出結果如下圖:

現在可以考慮一下下面的**段,它展示了重複的元素是如何被剔除的。

static void main(string args)

;hashsethashset = new hashset(cities);

foreach (var city in hashset)

}

當你執行完上面的程式,重複的城市名稱已經被移除了。

從hashset 中刪除某乙個元素可以呼叫 remove 方法,它的語法結構如下:

public bool remove (t item);
如果在集合中找到了這個元素,remove方法將會刪除這個元素並且返回true,否則返回 false。

下面的**片段展示了如何使用 remove 方法刪除 hashset 中的元素

string item = "d";

if(hashset.contains(item))

如果你想刪除 hashset 中的所有元素,可以呼叫 clear 方法。

hashset提供了非常多的方法用於set集合操作上,比如說:intersectwith, unionwith, ispropersubsetof, exceptwith, 和 symmetricexceptwith

這個 ispropersubsetof 用於判斷 hashset 是否為某乙個集合的完全子集,可以看下面的例子:

hashsetseta = new hashset() ;

hashsetsetb = new hashset() ;

hashsetsetc = new hashset() ;

if (seta.ispropersubsetof(setc))

console.writeline("setc contains all elements of seta.");

if (!seta.ispropersubsetof(setb))

console.writeline("setb does not contains all elements of seta.");

如果你執行了上面這個程式,你會在控制台上看到如下的輸出:

unionwith方法常用於集合的合併,比如說下面的**:

hashsetseta = new hashset() ;

hashsetsetb = new hashset() ;

seta.unionwith(setb);

foreach(string str in seta)

當你執行完上面的**,setb 集合會被 seta 集合吞掉,最後 seta 集合將會是包括:"a", "b", "c", "d", "e", "x", and "y"

intersectwith 方法常用於表示兩個 hashset 的交集,下面的例子或許會讓你更加理解:

hashsetseta = new hashset() ;

hashsetsetb = new hashset() ;

seta.intersectwith(setb);

foreach (string str in seta)

當你執行了上面的這段程式,只有兩個 hashset 中都存在的元素才會輸出到控制台中,輸出結果如下所示:

exceptwith 方法表示數學上的減法操作,這個時間複雜度是 o(n),假定你有兩個hashset 集合,分別叫 seta 和 setb,並且用了下面的語句。

seta.exceptwith(setb);
它返回的元素為: seta中有,setb中沒有 的最終結果,如果還不明白的話,使用如下**輔助理解:

hashsetseta = new hashset() ;

hashsetsetb = new hashset() ;

seta.exceptwith(setb);

foreach (string str in seta)

當你執行了上面這段程式,元素 b,d,e 將會輸出到控制台上。

symmetricexceptwith 方法常用於修改乙個 hashset 來存放兩個 hashset 都是唯一的元素,換句話說,我要的就是兩個集合都不全有的元素,如果還不明白的話,考慮下面的**段:

hashsetseta = new hashset() ;

hashsetsetb = new hashset() ;

seta.symmetricexceptwith(setb);

foreach (string str in seta)

當你執行完上面的**,你會發現,seta中有而setb中沒有 和 setb中有而seta中沒有的元素將會輸出到控制台中。

我們知道陣列的平均複雜度是 o(n),這裡的 n 表示陣列裡的元素數量,而訪問 hashset 中的某乙個元素,它的複雜度為 o(1),這個常量複雜度就決定了 hashset 在快速檢索 和執行 set集合 操作上是乙個非常好的選擇,你也可以使用 list 去儲存某些有指定順序的元素,同時也可以包含重複的值。

更多高質量乾貨:參見我的 github: dotnetfly

如何使用 C 中的 Tuple

開局一張圖,首先宣告的是 tuple 不是什麼新鮮概念,在程式語言 f python 中早就有這個了,tuple 是一種 有序的,有限不可變的,支援混雜型別的固定個數的 一種資料結構,有些朋友可能就想問了,這裡的混雜是什麼意思?其實就是說 tuple 中的若干元素型別,即可以是同型別,也可以是不同型...

set中的hashSet和treeSet相關概念

簡而言之,帶hashcode的資料集,都犧牲空間帶有乙個hash對映表,能進行快速的匹配查詢。帶tree的資料集可以認為是一棵有序的樹形結構。那麼,hashcode結構不再具體詳細說明。下來詳細說下treeset中的排序問題,分成自然排序,和自定義排序 1.自然排序是讓set內部的元素自身實現com...

c 中enum 如何使用

在生活中,列舉的例子隨處可見,比如禮拜幾,那麼就可以作為乙個列舉變數。這個變數所儲存的值,是有限的,且,能被我們所列舉。再比較說,性別。它也可以作為乙個列舉型別,我們知道,性別也就只有 男 或者 女 它是可以被我們所列舉的。它能很直觀的表達出我們所定義的事件。如 定義乙個列舉型別的變數,雖然不知道變...