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