C++ unordered_map和unordered_set的使用示例詳解
1.unordered_set系列的使用
1.1unordered_set和unordered_multiset參考文檔
<unordered_set> - C++ Reference
1.2unoredered_set類的使用
●unordered_set的聲明如下,Key就是unordered_set底層關鍵字的類型
●unordered_set默認要求Key支持轉(zhuǎn)換為整型,若不支持或想按自己的需求走可以自己實現(xiàn)支持將Key轉(zhuǎn)成整型的仿函數(shù)傳給第二個模板參數(shù)
●unordered_set默認要求支持比較相等,若不支持或想按自己的需求走可以自己實現(xiàn)支持將Key比較相等的仿函數(shù)傳給第三個模板參數(shù)
●unordered_set底層存儲數(shù)據(jù)的內(nèi)存是從空間配置器申請的,若需要可以自己實現(xiàn)內(nèi)存池,傳給第四個參數(shù)
●一般情況下,不需要傳后三個模板參數(shù)
●unordered_set底層是用哈希桶實現(xiàn),增刪查改平均效率是O(1),迭代器遍歷不再有序,為了跟set區(qū)分,所以取名unoredered_set
●set和unordered_set的功能高度相似,只是底層不同,有一些性能和使用的差異。
template<class Key, //unoredered_set::key_type/value_type
class Hash=hash<Key>, //unoredered_set::hasher
class Pred=equal_to<Key>, //unoredered_set::key_equal
class Alloc=allocator<Key> //unoredered_set::allocator_type
> class unordered_set;1.3unordered_set和set的使用差異
●unordered_set的支持增刪查改和set的使用一摸一樣。
●unordered_set和set的第一個差異是對key的要求不同,set要求Key支持小于比較,而unordered_set要求Key支持轉(zhuǎn)成整型且支持等于比較,本質(zhì)是哈希表的要求。
●unordered_set和set的第二個差異是迭代器的差異,set的iterator是雙向迭代器,unordered_set是單向迭代器,其次set底層是紅黑樹,紅黑樹是二叉搜索樹,走中序遍歷是有序的,所以set迭代器是有序+去重;而unordered_set底層是哈希表,迭代器遍歷是無序+去重。
●unordered_set和set第三個差異是性能的差異,整體而言大多數(shù)場景下,unordered_set的增刪查改更快一些,因為紅黑樹增刪查改效率是O(logN),而哈希表增刪查改平均效率是O(1)。
pair<iterator,bool> insert(const value_type& val); size_type erase(const key_type& k); iterator find(const key_type& k);
int test_set(){
const size_t N=1000000;
unordered_set<int> us;
set<int> s;
vector<int> v;
v.reserve(N);
srand(time(0));
for(size_t i=0;i<N;i++){
//v.push_back(rand()); //N比較大時,重復值比較多
v.push_back(rand()+i); //重復值相對少
//v.push_back(i); //沒有重復,有序
}
size_t begin1=clock();
for(auto e:v)
s.insert(e);
size_t endl=clock();
cout<<"set insert:"<<endl-begin1<<endl;
size_t begin2=clock();
for(auto e:v)
us.insert(e);
size_t end2=clock();
cout<<"unordered_set insert:"<<end2-begin2<<endl;
int m1=0;
size_t begin3=clock();
for(auto e:v){
auto ret=s.find(e);
if(ret!=s.end()){
++m1;
}
}
size_t end3=clock();
cout<<"set find:"<<end3-begin3<<"->"<<m1<<endl;
int m2=0;
size_t begin4=clock();
for(auto e:v){
auto ret=us.find(e);
if(ret!=us.end()){
++m1;
}
}
size_t end4=clock();
cout<<"unordered_set find:"<<end4-begin4<<"->"<<m2<<endl;
cout<<"插入數(shù)據(jù)個數(shù):"<<s.size()<<endl;
cout<<"插入數(shù)據(jù)個數(shù):"<<us.size()<<endl;
size_t begin5()=clock();
for(auto e:v)
s.erase(e);
size_t end5=clock();
cout<<"set erase:"<<end5-begin5<<endl;
size_t begin6()=clock();
for(auto e:v)
us.erase(e);
size_t end6=clock();
cout<<"unordered_set erase:"<<end6-begin6<<endl;
return 0;
}
int main(){
test_set();
return 0;
}1.4unordered_map和map的使用差異
●unordered_map的支持增刪查改跟map的使用一模一樣。
●unordered_map和map的第一個差異是對key的要求不同,map要求Key支持小于比較,而unordered_map要求Key支持轉(zhuǎn)成整型且支持等于比較,本質(zhì)是哈希表的要求。
●unordered_map和map的第二個差異是迭代器的差異,map的iterator是雙向迭代器,unordered_map是單向迭代器,其次map底層是紅黑樹,紅黑樹是二叉搜索樹,走中序遍歷是有序的,所以map迭代器遍歷是Key有序+去重。而unordered_map底層是哈希表,迭代器遍歷是Key無序+去重。
●unordered_map和map的第三個差異是性能的差異,整體而言大多數(shù)場景下,unordered_map的增刪查改更快一些,因為紅黑樹增刪查改效率是O(logN),而哈希表增刪查改平均效率是O(1)。
pair<iterator,bool> insert(const value_type& val); size_type erase(const key_type& k); iterator find(const key_type& k); mapped_type& operator[](const key_type& k);
1.5unordered_multimap/unordered_multiset
●unordered_multimap/unordered_multiset跟multimap/multiset功能完全類似,支持Key冗余。
●unordered_multimap/unordered_multiset跟multimap/multiset的差異也是三個方面的差異,key的要求的差異,iterator及遍歷順序的差異,性能的差異。
到此這篇關于C++ unordered_map和unordered_set的使用示例詳解的文章就介紹到這了,更多相關C++ unordered_map和unordered_set使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
簡單分析C語言中指針數(shù)組與數(shù)組指針的區(qū)別
這篇文章主要介紹了C語言中指針數(shù)組與數(shù)組指針的區(qū)別,是C語言入門學習中的基礎知識,需要的朋友可以參考下2015-11-11
使用C++實現(xiàn)Excel文件與CSV之間的相互轉(zhuǎn)換
這篇文章主要為大家詳細介紹了如何使用C++實現(xiàn)Excel文件與CSV之間的相互轉(zhuǎn)換,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-06-06
C++的cout.tellp()和cout.seekp()語法介紹
無論是使用 cout 輸出普通數(shù)據(jù),用 cout.put() 輸出指定字符,還是用 cout.write() 輸出指定字符串,數(shù)據(jù)都會先放到輸出流緩沖區(qū),待緩沖區(qū)刷新,數(shù)據(jù)才會輸出到指定位置,本文給大家介紹一下C++的cout.tellp()和cout.seekp()語法,需要的朋友可以參考下2023-09-09

