STL中map、set、unordered_map、unordered_set定義時的重載方式


Set、Map:

對於map、set來說如果是基本類型,默認從小到大。但如果是自定義類型或者非基本類型(比如vector這種),那么就需要自己重載相應的規則。

舉例:

我知道的map重載從大到小的幾種方法:

1、Lambda:

auto cmp=[](int x,int y){return x>y;};
map<int,int,decltype(cmp)> p(cmp);

2、定義比較函數:

bool cmp(int x,int y){
    return x>y;
}
map<int,int,decltype(cmp)> p(cmp);

3、結構體作為key的話,結構體中重載小於號(重載大於號也可以)

struct eg
{
    int x,y;
    eg(int a,int b):x(a),y(b){}
    bool operator<(const eg& other)const{
        return x>other.x;
    }
};

int main()
{
    map<eg,int> p;
    p[eg(1,2)]=1;
    getchar();
}

4、利用仿函數(在類中重載函數運算符)

struct eg
{
    int x,y;
    eg(int a,int b):x(a),y(b){}
    // bool operator<(const eg& other)const{
    //     return x>other.x;
    // }
};

struct cmp{
    bool operator() (const eg& a,const eg& b){
        return a.x>b.x;
    }
};
int main()
{
    map<eg,int,cmp> p;
    p[eg(1,2)]=1;
    getchar();
}

對於set來說也是一樣的,大家自己試試就好了。

 

unordered_map和unordered_set:

這兩種容器內部實現是HASH表,並且本身就是無序的,所以不需要之前map和set的比較大小函數,而是需要一種唯一映射key的方式。

這兩種容器的Key如果是非基本類型or自定義類型,我們就需要指定一個hash函數。比如我們定義了一個類info,里面有學號、姓名、班級等等。系統不知道怎么確定不同的info變量是不是應該映射到一個值還是不同的值。

當然我們本身是希望系統按照學號給我們Hash就好了,即把學號作為主鍵。但系統不知道呀,所以我們得告訴它怎么來計算哈希。並且經過我的測試還需要重載==號,可能是當hash值相同的情況下比較元素到底相同還是不同用的。

用法如下:

struct eg
{
    int x,y;
    eg(int a,int b):x(a),y(b){}
    bool operator==(const eg& other) const{//這個重載==號必須要寫,否則報錯
        return x==other.x and y==other.y;
    }
};

struct eg_hash
{
    size_t operator() (const eg& a)const{//利用x的hash值和y的hansh值做異或得到eg的hash值
        return hash<int>()(a.x) ^ hash<int>()(a.y);
    }
};

int main()
{
    unordered_map<eg,int,eg_hash> mp;
    unordered_set<eg,eg_hash> st;
    mp[eg(1,2)]=1;
    mp[eg(5,3)]=55;
    st.insert(eg(534,4235));
    st.insert(eg(5,634));
    getchar();
}

 

其中hash<int>()是一個hash模板類對象。該類重載了函數調用運算符,所以我們使用hash<int>()(xxxx)來計算xxxx的哈希值。

我們也可以寫為:hash<int>().operator()(a.x)

如果你覺得兩個括號不好理解的話,可以分兩步寫:

auto MyHash=hash<int>();  //創造一個hash模板類對象
int hash_result=MyHash(a.x)    //或者 MyHash.operator(a.x)

 


免責聲明!

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



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