C++ STL 之 unordered_set 使用(包括unordersd_map)
哈希表的實現復雜了該容器上的雙向遍歷,似乎沒有一種合適的方法能夠做到高效快速。 因此,unorder版本的map和set只提供前向迭代器(非unorder版本提供雙向迭代器)。
首先要include這個unordered_set頭文件。
然后就是第六行我們定義了一個整型int的集合,叫myset。
后面幾行,我們演示了insert/find/erase的用法。
有兩點需要注意:
一是這個容器是個集合,所以重復插入相同的值是沒有效果的。大家可以看到我們這里第7行和第9行插入了2次3,實際上這個集合里也只有1個3,第10行輸出的結果是2。
二是find的返回值是一個迭代器(iterator),如果找到了會返回指向目標元素的迭代器,沒找到會返回end()。
對于unordered_set,insert/find/erase的平均復雜度是O(1),但是最壞復雜度是O(N)的,這里N是指容器中元素數量。
有兩種情況會出現O(N)復雜度。
1是你的哈希函數太爛了,導致很多不同元素的哈希值都相同,全是碰撞,這種情況復雜度會變成O(N)。但是這種情況一般不用擔心,因為對于string以及int double之類的基本數據類型,都有默認的哈希函數,而且默認的哈希函數足夠好,不會退化到O(N)。如果是你自定義的哈希函數,那你要小心一點,別寫的太差了。
2是如果insert很多數據,會觸發rehash。就是整個哈希表重建。這個過程有點類似向vector里不斷添加元素,vector會resize。比如你新建一個vector時,它可能只申請了一塊最多保存10個元素的內存,當你插入第11個元素的時候,它會自動重新申請一塊更大空間,比如能存下20個元素。哈希表也是類似,不過rehash不會頻繁發生,均攤復雜度還是O(1)的,也不用太擔心。
unordered_set是一個集合,有的時候我們需要一個字典,就是保存一系列key/value對,并且可以按key來查詢。比如我們要保存很多同學的成績,每位同學有一個學號,也有一個分數,我們想按學號迅速查到成績。這時候我們就可以用unordered_map。
unordered_map同樣也提供了增刪查函數:
unordered_map::insert
unordered_map::find
unordered_map::erase
這三個函數的平均時間復雜度也是O(1)的。我們可以看一個例子:
首先我們看第2行,要用unordered_map你要先include相應的頭文件。
在7行我們定義了一個mymap,它的key是string類型,字符串;value是整形。
第8第9行展示的insert插入,因為我們這里要插入的是一個key/value pair(鍵值對),我們要用make_pair函數把一個字符串和一個整數打包成一個pair。
第10行是find查找,find返回的也是一個迭代器,iterator。這里我們懶得寫很長的迭代器類型,直接用的auto。auto是c++11標準里的關鍵字,它會自動推斷變量的類型。如果你的編譯器不支持c++11,那你還是要老老實實寫全:unordered_map<string, int>::iterator
迭代器指向的是一個pair,所以第11行我們可以用first和second去拿到對應的key和value,這里first是”c++”這個字符串,second是100這個整數。
第13第14行展示了一下erase刪除。
值得一提的是,unordered_map重載了[]運算符,我們可以把key放在中括號里,像操作數組一樣操作unordered_map:
上面這個程序的輸出結果是101。大家可以看一下第8~第10行。我們把”c++”這個key放在中括號里就能直接操作”c++”對應的值。這種寫法會讓程序更直觀。
---------------------?
作者:夏普通?
來源:CSDN?
原文:https://blog.csdn.net/qq_34243930/article/details/81456582?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
————————————————————————————————————————————————————————
unordered_set與與unordered_map相似,這次主要介紹unordered_set
unordered_set它的實現基于hashtable,它的結構圖仍然可以用下圖表示,這時的空白格不在是單個value,而是set中的key與value的數據包
有unordered_set就一定有unordered_multiset.跟set和multiset一樣,一個key可以重復一個不可以
unordered_set是一種無序集合,既然跟底層實現基于hashtable那么它一定擁有快速的查找和刪除,添加的優點.基于hashtable當然就失去了基于rb_tree的自動排序功能
unordered_set無序,所以在迭代器的使用上,set的效率會高于unordered_set
注:
一是這個容器是個集合,所以重復插入相同的值是沒有效果的。大家可以看到我們這里第7行和第9行插入了2次3,實際上這個集合里也只有1個3,第10行輸出的結果是2。
二是find的返回值是一個迭代器(iterator),如果找到了會返回指向目標元素的迭代器,沒找到會返回end()。
對于unordered_set,insert/find/erase的平均復雜度是O(1),但是最壞復雜度是O(N)的,這里N是指容器中元素數量。
?
?
參數1 _Value key和value的數據包
參數2 _Hash hashfunc獲取hashcode的函數
參數3 _Pred 判斷key是否相等
參數4 分配器
下面介紹一下unordered_set的基本使用,最后我會分享一下我的測試代碼
?
一 定義
?
?
?
二 容量操作
?
?
三 迭代器操作
?
四 基本操作
?五 籃子操作
?
六 內存操作
?
七 hash func
unordered_set注意事項
for(auto it=v.begin();it!=v.end();it++) //auto是c++11標準里的關鍵字,它會自動推斷變量的類型。 //如果你的編譯器不支持c++11, //那你還是要老老實實寫全:unordered_map<string, int>::iterator //v.begin()返回的是一個指針類型所以想要具體的值還需要在前面加上* set.find(key) //如果key不存在,那么返回set.end()unordered_map注意事項
class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> map;for(int i=0;i<nums.size();i++){auto it=map.find(target-nums[i]);if(it!=map.end()) return {it->second,i};map[nums[i]]=i;//或者 map.insert(make_pair(nums[i],i));}return {};} };上面這一段代碼中注意以下幾點
1.使用find(key)方法時,參數是key,同樣的也是返回指針類型 2.key值保存在it->first中,value保存在it->second中 3.當我們使用insert方法插入鍵值對的時候需要在使用鍵值對函數make_pair() 4.我們還可以直接使用map[key]=value的方法 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的C++ STL 之 unordered_set 使用(包括unordersd_map)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Javaweb基础——Servlet
- 下一篇: leetcode(1)485——最大连续