set、multiset的自定义类型的自定义排序规则的两种方法(C++)

本文介绍了如何在C++中使用set容器时,通过自定义数据类和比较函数,实现年龄与姓名混合排序。方法一是定义message类和messageCmp比较类,方法二是通过函数指针传递自定义排序规则。两种方法都展示了如何绕过默认的key类型排序,实现复杂条件下的元素顺序控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于像set、multiset之类有序容器,默认情况下,标准库使用关键字类型(key)的<运算符来比较两个关键词。

    set<int> set ;

    set.insert(7);
    set.insert(3);
    set.insert(10);

    for (auto it = set.begin(); it != set.end(); ++it)
        cout<<*it<<endl;

在这里插入图片描述
插入顺序是7、3、10,但是遍历map,得到的是3、7、10,这就是默认情况下int的<运算符在发挥作用,一般情况下都能满足要求。

但是要是我们不需要自定义的排序规定,想要自己定义规则,怎么办?

比如现在有两个数据,第一个是年龄,第二个是名字,年龄从小到大排序,如果年龄相同,按字符串排序方式。有些人可能想用map<int, string>, 但是map的排序规则也是针对key,就是前面那个int,不会探究后面那个string。

方法1:定义一个数据类和比较类

这个时候可以自定义一个数据类,这个类就包含两个数据成员,一个age,一个name,还有一个构造函数。然后定义一个比较类,对message进行自定义的比较规则。如果年龄相等,比较名字。如果年龄不相等,比较年龄。

class message {
    public:
        int age;
        string name;
        message(int x, string y): age(x),name(y){};
};

class messageCmp {
    public:
        bool operator()(const message &a, const message &b) {
            if (a.age == b.age)
                return a.name < b.name;
            else
                return a.age < b.age;

        }
};

接着我们定义具备messageCmp规则的set,插入三个值。对于字符串“Jbse”和“Jane”,因为前者第二个字母是b,后者第二个字母是a,所以后者比较小。可以看到输出是按照我们预想的排序进行。

set<message, messageCmp> set ;

set.insert(message(7,"Tony"));
set.insert(message(4,"Jbse"));
set.insert(message(4,"Jane"));

for (auto it = set.begin(); it != set.end(); ++it)
    cout<<it->age<<"->"<<it->name<<endl;

在这里插入图片描述

方法2:定义一个比较函数

这是另外的一种方式,创建了一个新的函数。

bool messageCmp(const message &a, const message &b) {
            if (a.age == b.age)
                return a.name < b.name;
            else
                return a.age < b.age;
        }

int main() {

    set<message, decltype(messageCmp)*> set(messageCmp) ;

    set.insert(message(7,"Tony"));
    set.insert(message(4,"Jbse"));
    set.insert(message(4,"Jane"));

    for (auto it = set.begin(); it != set.end(); ++it)
        cout<<it->age<<"->"<<it->name<<endl;

在这里插入图片描述
在定义set的时候必须提供两个类型:关键字类型,即message,以及比较操作类型(一种函数指针类型),指向messageCmp函数。

C++11新标准引入了类型指示符decltype,它的作用是返回操作数的数据类型。decltype的结果是函数类型,所以只有在后面加上*才能表示给定函数类型的指针。用messageCmp来初始化set,表示我们在往set添加元素的时候,通过调用messageCmp函数为元素排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值