C++ 在容器类中使用自定义比较器的排序集

C++ Sorting set using custom comparator in a container class

本文关键字:比较器 排序 自定义 容器类 C++      更新时间:2023-10-16

>我有一个有名字和年龄的类人。

我有一个名为 people 的容器类,它存储一组人员。

我创建了两个自定义比较器,按名称和年龄排序。

当我在我的类(人)中存储包含人员的集合时,如何将自定义比较器传入。

例如

我的比较器看起来像这样

struct compareByName
{
    bool operator()(const Person & Left, const Person & Right)
    {
        return (Left.getName() < Right.getName());
    }
};

总的来说,如果我想按名字对一组人进行排序,我只是这样做

set<Person, compareByName> peopleByName;

或者对于年龄我做

set<Person, compareByAge> peopleByAge;

我遇到问题的地方是如何在我的人员容器类中使用它我会有类似的东西

class People
{
private:
    set<Person, COMPARATOR> m_people;
}

比较器可以是按姓名或年龄

您可以使用

std::function作为比较器类型,然后为构造函数提供特定的比较器:

class People
{
    using PeopleSet = set<Person, std::function<bool(const Person &p1, const Person &p2 )>>;
    People() : people( compareByName() ) {}
    void sortByAge();
private:
    PeopleSet people; 
};

注意 创建 SET 后无法更改比较器,必须创建另一个实例:

void People::sortByAge()
{
    people = PeopleSet( people.begin(), people.end(), compareByAge() );
}

这将涉及复制或移动整个集合。如果您希望能够同时使用两种方式,请改用boost::multi_index

您可以通过模板进行操作:

#include <iostream>
#include <string>
#include <set>
class Person 
{
private:
    std::string name;
    int age;
public:
    Person(std::string name, int age) : name(name), age(age) {};
    std::string getName() const { return name; };
    int getAge() const { return age; };
};
template<class COMPARATOR> class People
{
private:
    std::set<Person, COMPARATOR> m_people;
public:
    void AddPerson(Person const &p)
    {
        m_people.insert(p);
    }
    void PrintPeople()
    {
        for (Person p : m_people)
        {
            std::cout << p.getName() << " - " << p.getAge() << std::endl;
        }
    }
};
struct SortedByName
{
    bool operator()(const Person & Left, const Person & Right)
    {
        return (Left.getName() < Right.getName());
    }
};
struct SortedByAge
{
    bool operator()(const Person & Left, const Person & Right)
    {
        return (Left.getAge() < Right.getAge());
    }
};

int main()
{
    Person p1("Bob", 21);
    Person p2("Jack", 13);
    Person p3("Kath", 33);
    People<SortedByName> ppl1;
    ppl1.AddPerson(p1);
    ppl1.AddPerson(p2);
    ppl1.AddPerson(p3);
    std::cout << "By Name:" << std::endl;
    ppl1.PrintPeople();
    std::cout << std::endl;
    People<SortedByAge> ppl2;
    ppl2.AddPerson(p1);
    ppl2.AddPerson(p2);
    ppl2.AddPerson(p3);
    std::cout << "By Age:" << std::endl;
    ppl2.PrintPeople();
    return 0;
}

指纹:

By Name:
Bob - 21
Jack - 13
Kath - 33
By Age:
Jack - 13
Bob - 21
Kath - 33