STL標准庫-容器-unordered_set


技術在於交流、溝通,本文為博主原創文章轉載請注明出處並保持作品的完整性

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

template<class _Value,
class _Hash = hash<_Value>,
class _Pred = std::equal_to<_Value>,
class _Alloc = std::allocator<_Value> >
class unordered_set
: public __unordered_set<_Value, _Hash, _Pred, _Alloc>
{
typedef __unordered_set<_Value, _Hash, _Pred, _Alloc> _Base;

...

}  

 

參數1 _Value key和value的數據包

參數2 _Hash hashfunc獲取hashcode的函數

參數3 _Pred 判斷key是否相等

參數4 分配器

下面介紹一下unordered_set的基本使用,最后我會分享一下我的測試代碼


 

一 定義

    //定義
    unordered_set<int> c1;
    
    //operator=
    unordered_set<int> c2;
    c2 = c1;

 

 


 

二 容量操作

//判斷是否為空
    c1.empty();
    
    //獲取元素個數 size()
    c1.size();
    
    //獲取最大存儲量 max_size()
    c1.max_size();

 


 

三 迭代器操作

    //返回頭迭代器 begin()
    unordered_set<int>::iterator ite_begin = c1.begin();
    
    //返回尾迭代器 end()
    unordered_set<int>::iterator ite_end = c1.end();
    
    //返回const頭迭代器 cbegin()
    unordered_set<int>::const_iterator const_ite_begin = c1.cbegin();
    
    //返回const尾迭代器 cend()
    unordered_set<int>::const_iterator const_ite_end = c1.cend();
    
    //槽迭代器
    unordered_set<int>::local_iterator local_iter_begin = c1.begin(1);
    unordered_set<int>::local_iterator local_iter_end = c1.end(1);

 

四 基本操作

    //查找函數 find() 通過給定主鍵查找元素
    unordered_set<int>::iterator find_iter = c1.find(1);
    
    //value出現的次數 count() 返回匹配給定主鍵的元素的個數
    c1.count(1);
    
    //返回元素在哪個區域equal_range() 返回值匹配給定搜索值的元素組成的范圍
    pair<unordered_set<int>::iterator, unordered_set<int>::iterator> pair_equal_range = c1.equal_range(1);
    
    //插入函數 emplace()
    c1.emplace(1);
    
    //插入函數 emplace_hint() 使用迭代器
    c1.emplace_hint(ite_begin, 1);
    
    //插入函數 insert()
    c1.insert(1);
    
    //刪除 erase()
    c1.erase(1);//1.迭代器 value 區域
    
    //清空 clear()
    c1.clear();
    
    //交換 swap()
    c1.swap(c2);

 五 籃子操作

    //籃子操作 籃子個數 bucket_count() 返回槽(Bucket)數
    c1.bucket_count();
    
    //籃子最大數量 max_bucket_count() 返回最大槽數
    c1.max_bucket_count();
    
    //籃子個數 bucket_size() 返回槽大小
    c1.bucket_size(3);
    
    //返回籃子 bucket() 返回元素所在槽的序號
    c1.bucket(1);
    
    //    load_factor    返回載入因子,即一個元素槽(Bucket)的最大元素數
    c1.load_factor();
    
    //    max_load_factor    返回或設置最大載入因子
    c1.max_load_factor();

 

六 內存操作

    //    rehash    設置槽數
    c1.rehash(1);
    
    //    reserve    請求改變容器容量
    c1.reserve(1000);

 

七 hash func

    //hash_function() 返回與hash_func相同功能的函數指針
    auto hash_func_test = c1.hash_function();
    
    //key_eq() 返回比較key值得函數指針
    auto key_eq_test = c1.key_eq();

 

八 測試代碼

#include <iostream>
#include <unordered_set>
using namespace std;

namespace wzj001{
    void coutUnorderedSet(std::unordered_set<int>& m, string funcName) {
        std::unordered_set<int>::iterator it;
        std::cout << funcName << ": ";
        for ( it = m.begin(); it != m.end(); it++ )
            std::cout << *it << " ";
        std::cout << std::endl;
    }
    
    void initUnorderSet(unordered_set<int>& tmp)
    {
        for(int i = 0; i < 10; i++)
            tmp.insert(i);
    }
    
    string turnBoolToString(bool tmp)
    {
        return tmp ? "true" : "false";
    }
    
    void basicOperationUnorderedSet()
    {
        //定義
        std::unordered_set<int> c;
        // 普通插入,返回pair<迭代器,插入是否成功>
        pair<unordered_set<int>::iterator, bool> c_insert = c.insert(1);
        cout << "指向key的迭代器: " << *c_insert.first  << "   插入是否成功 "<< turnBoolToString(c_insert.second)<<endl;
        pair<unordered_set<int>::iterator, bool> c_insert2 = c.insert(2);
        cout << "指向key的迭代器: " << *c_insert2.first << "   插入是否成功 "<< turnBoolToString(c_insert2.second)<<endl;
        pair<unordered_set<int>::iterator, bool> c_insert3 = c.insert(1);
        cout << "指向key的迭代器: " << *c_insert3.first << "   插入是否成功 "<< turnBoolToString(c_insert3.second)<<endl;
        
        //按指定區域插入
        std::unordered_set<int> c_insert_region;
        c_insert_region.insert(c.begin(), c.end());
        coutUnorderedSet(c_insert_region, "按指定區域插入");
        
        //構造插入
        std::unordered_set<int> c_emplace;
        c_emplace.emplace(1);
        c_emplace.emplace(2);
        c_emplace.emplace(3);
        coutUnorderedSet(c_emplace, "構造插入");
        
        //迭代器插入
        std::unordered_set<int> c_emplace_hint;
        c_emplace_hint.emplace_hint(c_emplace_hint.begin(), 1);
        c_emplace_hint.emplace_hint(c_emplace_hint.begin(), 2);
        c_emplace_hint.emplace_hint(c_emplace_hint.begin(), 3);
        coutUnorderedSet(c_emplace_hint, "迭代器插入");
        
        //刪除
        std::unordered_set<int> c_erase;
        initUnorderSet(c_erase);
        coutUnorderedSet(c_erase, "初始化c_erase");
        //指定位置刪除
        c_erase.erase(c_erase.begin());
        coutUnorderedSet(c_erase, "指定位置刪除");
        
        //指定key刪除
        c_erase.erase(8);
        coutUnorderedSet(c_erase, "指定key刪除");
        
        //指定區域刪除
        c_erase.erase(c_erase.begin(), c_erase.end());
        coutUnorderedSet(c_erase, "指定區域刪除");
        
        //交換
        c.swap(c_emplace);
        coutUnorderedSet(c, "交換");
        
    }
    
    void unorderSetElementLookup()
    {
        //查找
        std::unordered_set<int> c_find;
        initUnorderSet(c_find);
        std::unordered_set<int>::iterator find_iter = c_find.find(10);
        if(find_iter != c_find.end())
        {
            cout<< "找到元素 : "<< *find_iter << endl;
        }
        else
            cout<< "沒找到 !"<< endl;
        
        cout << "value出現次數 :" <<c_find.count(1)<< endl; //set key不可重復
        
        pair<std::unordered_set<int>::iterator, std::unordered_set<int>::iterator> tmp = c_find.equal_range(5);
        
        if(tmp.first != c_find.end()&& tmp.second != c_find.end())
        {
            cout << "該值所在區間為[" << *tmp.first << "," << *tmp.second << "]" << endl;
        }
    }
    
    void unorderSetBuckets()
    {
        //籃子操作
        std::unordered_set<int> c_buckets;
        initUnorderSet(c_buckets);
        cout << "籃子個數: "    << c_buckets.bucket_count()<< endl;
        cout << "籃子大小: " << c_buckets.bucket_size(1) << endl;
        cout << "最大籃子個數: " << c_buckets.max_bucket_count() << endl;
        cout << "該值所在籃子序號: " << c_buckets.bucket(3) << endl;
    }
    
    void unorderSetHashPolicy()
    {
        std::unordered_set<int> c_;
        cout << "負載: "<< c_.load_factor()<< endl;
        initUnorderSet(c_);
        cout << "負載: "<< c_.load_factor()<< endl;//使用的籃子數/籃子總數  默認的籃子數為11
        cout << "最大負載: "<< c_.max_load_factor() << endl;
        c_.reserve(100);//預設籃子數 ,但是還沒有設定
        c_.rehash(3);//設定籃子數
    }
    
    void unorderSetObservers()
    {
        std::unordered_set<int> c_;
        initUnorderSet(c_);
        std::unordered_set<int>::hasher xxx = c_.hash_function();
        std::unordered_set<int>::key_equal zzz = c_.key_eq();
        cout << "hash_func: " << xxx(11111) << endl;
        cout << "key_eq: " << turnBoolToString(zzz(11111,11111)) << endl;
    }
}

int main()
{
    wzj001::basicOperationUnorderedSet();
    wzj001::unorderSetElementLookup();
    wzj001::unorderSetBuckets();
    wzj001::unorderSetHashPolicy();
    wzj001::unorderSetObservers();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM