如何对STL载体进行排序?

Nat*_*der 74 c++ sorting stl

我想排序一个 vector

vector<myClass> object;
Run Code Online (Sandbox Code Playgroud)

其中myclass包含许多int变量.如何对我vector的任何特定数据变量进行排序myClass.

ava*_*kar 113

std::sort(object.begin(), object.end(), pred());
Run Code Online (Sandbox Code Playgroud)

其中,pred()是一个定义对象上的顺序的函数对象myclass.或者,您可以定义myclass::operator<.

例如,您可以传递lambda:

std::sort(object.begin(), object.end(),
          [] (myclass const& a, myclass const& b) { return a.v < b.v; });
Run Code Online (Sandbox Code Playgroud)

或者如果您坚持使用C++ 03,那么函数对象方法(v是您要对其进行排序的成员):

struct pred {
    bool operator()(myclass const & a, myclass const & b) const {
        return a.v < b.v;
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 如果你没有这个特定类的泛型排序但只是想为这个向量排序,那么谓词方法比运算符重载方法要好得多. (8认同)

Gab*_*abe 77

超载运算符,然后排序.这是我在网上发现的一个例子......

class MyData
{
public:
  int m_iData;
  string m_strSomeOtherData;
  bool operator<(const MyData &rhs) const { return m_iData < rhs.m_iData; }
};

std::sort(myvector.begin(), myvector.end());
Run Code Online (Sandbox Code Playgroud)

来源:这里

  • @Neil,我发布了我发现的例子,因为我没有时间输入所有的老兄.IT是一个很好的例子,解决了这个问题.我很高兴你花了40分钟来决定投票.如果我不包括源站点,我可以看到它被低估了,但我做到了.这并不像我试图把它作为我自己的典当. (18认同)
  • 您将要生成op <()const,并将其参数作为const引用传递. (14认同)
  • @Neil我会承认,因为我使用过c ++已经有一段时间了,但我记得这个问题的一些一般性想法,这就是我回答的原因.我并不认为它是完美的,但它确实有效,我自己尝试过.我接受了你的建议并添加了它.如果你有其他一些问题,请说出来而不是那么居高临下.这样的行为不是,所以要么是老兄. (8认同)
  • 如果您尝试了它并且它"正常",您的编译器就会崩溃.请不要叫我"老兄". (4认同)
  • @gmcalab您对Neil的“ make op &lt;()const”含义的误解表明您并不真正理解所发布的代码。仅仅因为某些事情对您有用,并不意味着它是正确的事情。 (2认同)

Ste*_*sop 15

指向成员的指针允许您编写单个比较器,该比较器可以与您的类的任何数据成员一起使用:

#include <algorithm>
#include <vector>
#include <string>
#include <iostream>

template <typename T, typename U>
struct CompareByMember {
    // This is a pointer-to-member, it represents a member of class T
    // The data member has type U
    U T::*field;
    CompareByMember(U T::*f) : field(f) {}
    bool operator()(const T &lhs, const T &rhs) {
        return lhs.*field < rhs.*field;
    }
};

struct Test {
    int a;
    int b;
    std::string c;
    Test(int a, int b, std::string c) : a(a), b(b), c(c) {}
};

// for convenience, this just lets us print out a Test object
std::ostream &operator<<(std::ostream &o, const Test &t) {
    return o << t.c;
}

int main() {
    std::vector<Test> vec;
    vec.push_back(Test(1, 10, "y"));
    vec.push_back(Test(2, 9, "x"));

    // sort on the string field
    std::sort(vec.begin(), vec.end(), 
        CompareByMember<Test,std::string>(&Test::c));
    std::cout << "sorted by string field, c: ";
    std::cout << vec[0] << " " << vec[1] << "\n";

    // sort on the first integer field
    std::sort(vec.begin(), vec.end(), 
        CompareByMember<Test,int>(&Test::a));
    std::cout << "sorted by integer field, a: ";
    std::cout << vec[0] << " " << vec[1] << "\n";

    // sort on the second integer field
    std::sort(vec.begin(), vec.end(), 
        CompareByMember<Test,int>(&Test::b));
    std::cout << "sorted by integer field, b: ";
    std::cout << vec[0] << " " << vec[1] << "\n";
}
Run Code Online (Sandbox Code Playgroud)

输出:

sorted by string field, c: x y
sorted by integer field, a: y x
sorted by integer field, b: x y
Run Code Online (Sandbox Code Playgroud)


Ben*_*ier 9

与其他答案中解释的一样,您需要提供比较功能.如果你想保持该函数的定义接近于sort 调用(例如,如果它只对这种类型有意义),你可以在那里定义它boost::lambda.使用boost::lambda::bind调用成员函数.

例如,按成员变量或函数排序data1:

#include <algorithm>
#include <vector>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
using boost::lambda::bind;
using boost::lambda::_1;
using boost::lambda::_2;

std::vector<myclass> object(10000);
std::sort(object.begin(), object.end(),
    bind(&myclass::data1, _1) < bind(&myclass::data1, _2));
Run Code Online (Sandbox Code Playgroud)