c++数据结构,它根据成员的值自动对对象进行排序

c++ data structure that automatically sort objects by the value of a member

本文关键字:对象 排序 数据结构 成员 c++      更新时间:2023-10-16

在STL中,list是一种数据结构,可以根据数字的值自动对其进行排序。如果元素不是数字,而是类的实例,并且我希望容器根据类成员的值自动对元素进行排序,那么我应该使用什么样的容器?例如

class Rect{
    double height;
    double width;
    double area;
};

我希望容器按矩形的area自动排序。

您有用于自动订购容器的std::multiset

std::multiset<Rect, LessArea> rects;

LessArea

struct LessArea
{
    bool operator ()(const Rect& lhs, const Rect& rhs) const
    {
        return lhs.area < rhs.area;
    }
};

stl::priority_queue就是您想要的。只要用less<Rect>Rects上定义一个排序,或者用stl::priority_queue专门化Rect

如果你想自动排序,你必须做所谓的

1) 运算符过载小于<操作员

2) 比较器功能

对于您的任务,为了自动排序,在您编写了比较函数或重载<操作员,您可以使用

STL集合或优先级队列。这两个数据结构被定义为基于比较函数自动对元素进行排序。但这里需要注意的是,不能在中插入重复的元素集合,也就是说,如果两个矩形的面积相同,那么这些矩形中的第一个将保存在集合中。第二个不能插入。

使用std::set的程序如下所示。

class Rect{
    double height;
    double width;
    double area;
public:
    bool operator<( const Rect& rhs ) const
        { return area < rhs.area; }
};

您需要定义"<"运算符进行比较。请注意:std::set不允许同一个对象有多个副本。set中只能有唯一的元素。

我不介意使用向量,尤其是如果您希望能够存储重复的元素。通过使用一个简单的lambda函数,我们可以根据Rect的任何成员对对象进行排序。在本例中,我选择按区域对Rect对象进行排序。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Rect {
    Rect(double height, double width, double area) {
        _height = height;
        _width = width;
        _area = area;
    }
    double area() const {
        return _area;
    }
    // sorts Rect objects by ascending order of area
    static void sort_by_area(vector<Rect> &shapes) {
        sort(shapes.begin(), shapes.end(), [](const Rect &first, const Rec &second)
                                           { return first.area() < second.area); });
    }
private:
    double _height;
    double _width;
    double _area;
};
int main() {
    vector<Rect> r;
    r.push_back(Rect(0,0,3));
    r.push_back(Rect(0,0,2));
    r.push_back(Rect(0,0,4));
    for(auto &obj : r) {
        //prints 3 2 4
        cout << obj.area() << endl;
    }
    Rect::sort_by_area(r);
    for(auto &obj : r) {
        //prints 2 3 4
        cout << obj.area() << endl;
    }
    return 0;
}