sorting自定义对象的vector

如何sorting包含自定义(即用户定义)对象的vector。
应该使用标准的STLalgorithm和一个谓词(一个函数或一个函数对象),它们将在自定义对象中的一个字段上操作(作为sorting的关键)。
我在正确的轨道上?

一个简单的例子,使用std::sort

 struct MyStruct { int key; std::string stringValue; MyStruct(int k, const std::string& s) : key(k), stringValue(s) {} }; struct less_than_key { inline bool operator() (const MyStruct& struct1, const MyStruct& struct2) { return (struct1.key < struct2.key); } }; std::vector < MyStruct > vec; vec.push_back(MyStruct(4, "test")); vec.push_back(MyStruct(3, "a")); vec.push_back(MyStruct(2, "is")); vec.push_back(MyStruct(1, "this")); std::sort(vec.begin(), vec.end(), less_than_key()); 

编辑:正如Kirill V. Lyadvinsky所指出的那样,不是提供sorting谓词,而是可以实现operator< for MyStruct

 struct MyStruct { int key; std::string stringValue; MyStruct(int k, const std::string& s) : key(k), stringValue(s) {} bool operator < (const MyStruct& str) const { return (key < str.key); } }; 

使用这个方法意味着你可以简单地按如下方式对向量进行sorting

 std::sort(vec.begin(), vec.end()); 

Edit2:由于Kappabuild议你也可以通过override>操作符降序排列向量,并改变sorting调用一下:

 struct MyStruct { int key; std::string stringValue; MyStruct(int k, const std::string& s) : key(k), stringValue(s) {} bool operator > (const MyStruct& str) const { return (key > str.key); } }; 

你应该把它称为:

 std::sort(vec.begin(), vec.end(),greater<MyStruct>()); 

为了覆盖的利益。 我提出了一个使用lambdaexpression式的实现。

C ++ 11

 #include <vector> #include <algorithm> using namespace std; vector< MyStruct > values; sort( values.begin( ), values.end( ), [ ]( const MyStruct& lhs, const MyStruct& rhs ) { return lhs.key < rhs.key; }); 

C ++ 14

 #include <vector> #include <algorithm> using namespace std; vector< MyStruct > values; sort( values.begin( ), values.end( ), [ ]( const auto& lhs, const auto& rhs ) { return lhs.key < rhs.key; }); 

你可以使用functor作为std::sort第三个参数,或者你可以在你的类中定义operator<

 struct X { int x; bool operator<( const X& val ) const { return x < val.x; } }; struct Xgreater { bool operator()( const X& lx, const X& rx ) const { return lx.x < rx.x; } }; int main () { std::vector<X> my_vec; // use X::operator< by default std::sort( my_vec.begin(), my_vec.end() ); // use functor std::sort( my_vec.begin(), my_vec.end(), Xgreater() ); } 

你在正确的轨道上。 std::sort默认使用operator<作为比较函数。 所以为了sorting你的对象,你必须重载bool operator<( const T&, const T& )或者提供一个函数来进行比较,就像这样:

  struct C { int i; static bool before( const C& c1, const C& c2 ) { return c1.i < c2.i; } }; bool operator<( const C& c1, const C& c2 ) { return c1.i > c2.i; } std::vector<C> values; std::sort( values.begin(), values.end() ); // uses operator< std::sort( values.begin(), values.end(), C::before ); 

使用函子的好处是你可以使用一个函数来访问类的私有成员。

对typesX的自定义对象的这种vector或任何其他适用(可变input迭代器)范围进行sorting可以使用各种方法来实现,特别是包括使用标准库algorithm

  • sort
  • stable_sort
  • partial_sort
  • partial_sort_copy

由于大多数获得X元素的相对顺序的技术已经发布,我将从“为什么”和“何时”使用各种方法开始。

“最好”的做法将取决于不同的因素:

  1. 是sortingX对象的范围一个共同的或稀有的任务(这样的范围sorting在程序或库用户的多个不同的地方)?
  2. 所需的sorting“自然”(预期)还是有多种方式可以比较自己的types?
  3. 性能是一个问题还是应该sorting的X对象的范围是万无一失的?

如果Xsorting范围是一个常见的任务,并且实现的sorting是预期的(即X只是包装一个基本值),那么可能会超载operator<因为它允许sorting没有任何模糊(如正确传递适当的比较器)并一再产生预期的结果。

如果sorting是一个常见的任务,或者可能在不同的上下文中需要,但是有多个标准可以用来sortingX对象,我会去找Functors(自定义类的重载operator()函数)或函数指针一个用于词法sorting的函数/函数,另一个用于自然sorting)。

如果Xtypes的sorting范围在其他上下文中不常见或不太可能,我倾向于使用lambdaexpression式,而不是使用更多的函数或types混淆任何名称空间。

如果sorting不是以某种方式“清晰”或“自然”的话,情况尤其如此。 您可以很容易地在查看应用在原地的lambdaexpression式时查看后面的逻辑,而operator<是一见钟情的,您必须查看定义,才能知道将应用什么sorting逻辑。

但请注意,单个operator<定义是单点故障,而多个兰博是多个故障点,需要更多的注意。

如果operator<的定义在sorting完成/sorting模板被编译时不可用,那么编译器可能会在比较对象时被迫进行函数调用,而不是内联sorting逻辑,这可能是一个严重的缺陷(在至less当不应用链接时间优化/代码生成时)。

如何使用标准库sortingalgorithm来实现class X可比性

std::vector<X> vec_X; std::vector<Y> vec_Y;

1.重载T::operator<(T)operator<(T, T)并使用不需要比较函数的标准库模板。

重载成员operator<

 struct X { int i{}; bool operator<(X const &r) const { return i < ri; } }; // ... std::sort(vec_X.begin(), vec_X.end()); 

或免费operator<

 struct Y { int j{}; }; bool operator<(Y const &l, Y const &r) { return lj < rj; } // ... std::sort(vec_Y.begin(), vec_Y.end()); 

2.使用具有自定义比较函数的函数指针作为sorting函数参数。

 struct X { int i{}; }; bool X_less(X const &l, X const &r) { return li < ri; } // ... std::sort(vec_X.begin(), vec_X.end(), &X_less); 

3.为可以作为比较函数传递的自定义types创build一个bool operator()(T, T)重载。

 struct X { int i{}; int j{}; }; struct less_X_i { bool operator()(X const &l, X const &r) const { return li < ri; } }; struct less_X_j { bool operator()(X const &l, X const &r) const { return lj < rj; } }; // sort by i std::sort(vec_X.begin(), vec_X.end(), less_X_i{}); // or sort by j std::sort(vec_X.begin(), vec_X.end(), less_X_j{}); 

这些函数对象定义可以用C ++ 11和模板写得更通用:

 struct less_i { template<class T, class U> bool operator()(T&& l, U&& r) const { return std::forward<T>(l).i < std::forward<U>(r).i; } }; 

它可以用来sorting任何types的成员i支持<

4.将anonymus闭包(lambda)作为比较parameter passing给sorting函数。

 struct X { int i{}, j{}; }; std::sort(vec_X.begin(), vec_X.end(), [](X const &l, X const &r) { return li < ri; }); 

C ++ 14支持更通用的lambdaexpression式:

 std::sort(a.begin(), a.end(), [](auto && l, auto && r) { return li < ri; }); 

可以用macros包装

 #define COMPARATOR(code) [](auto && l, auto && r) -> bool { return code ; } 

使普通的比较器创build非常stream畅:

 // sort by i std::sort(v.begin(), v.end(), COMPARATOR(li < ri)); // sort by j std::sort(v.begin(), v.end(), COMPARATOR(lj < rj)); 

是的,与第三个参数(函数或对象)的std::sort() )会更容易。 一个例子: http : //www.cplusplus.com/reference/algorithm/sort/

在你的课堂上,你可能会重载“<”运算符。

 class MyClass { bool operator <(const MyClass& rhs) { return this->key < rhs.key; } } 

以下是使用lambdas的代码

 #include "stdafx.h" #include <vector> #include <algorithm> using namespace std; struct MyStruct { int key; std::string stringValue; MyStruct(int k, const std::string& s) : key(k), stringValue(s) {} }; int main() { std::vector < MyStruct > vec; vec.push_back(MyStruct(4, "test")); vec.push_back(MyStruct(3, "a")); vec.push_back(MyStruct(2, "is")); vec.push_back(MyStruct(1, "this")); std::sort(vec.begin(), vec.end(), [] (const MyStruct& struct1, const MyStruct& struct2) { return (struct1.key < struct2.key); } ); return 0; } 

您可以使用用户定义的比较器类。

 class comparator { int x; bool operator()( const comparator &m, const comparator &n ) { return mx<nx; } } 
  // sort algorithm example #include <iostream> // std::cout #include <algorithm> // std::sort #include <vector> // std::vector using namespace std; int main () { char myints[] = {'F','C','E','G','A','H','B','D'}; vector<char> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33 // using default comparison (operator <): sort (myvector.begin(), myvector.end()); //(12 32 45 71)26 80 53 33 // print out content: cout << "myvector contains:"; for (int i=0; i!=8; i++) cout << ' ' <<myvector[i]; cout << '\n'; system("PAUSE"); return 0; } 

为了sorting一个向量,你可以使用sort()algorithm。

 sort(vec.begin(),vec.end(),less<int>()); 

所使用的第三个参数可以更大或更小,或者也可以使用任何函数或对象。 但是,默认的操作符是<如果您将第三个参数留空。

 // using function as comp std::sort (myvector.begin()+4, myvector.end(), myfunction); bool myfunction (int i,int j) { return (i<j); } // using object as comp std::sort (myvector.begin(), myvector.end(), myobject); 
 typedef struct Freqamp{ double freq; double amp; }FREQAMP; bool struct_cmp_by_freq(FREQAMP a, FREQAMP b) { return a.freq < b.freq; } main() { vector <FREQAMP> temp; FREQAMP freqAMP; freqAMP.freq = 330; freqAMP.amp = 117.56; temp.push_back(freqAMP); freqAMP.freq = 450; freqAMP.amp = 99.56; temp.push_back(freqAMP); freqAMP.freq = 110; freqAMP.amp = 106.56; temp.push_back(freqAMP); sort(temp.begin(),temp.end(), struct_cmp_by_freq); } 

如果比较是错误的,它会做“交换”。