【问题标题】:C++ struct sortingC++ 结构排序
【发布时间】:2010-04-23 13:21:51
【问题描述】:
  • 我有一个自定义结构向量,每次都需要根据不同的标准进行排序
  • 实施运算符
  • 但我希望能够在每次调用 C++ 标准排序时指定排序标准。

怎么做?

  • 请注意,最好在运行时间上保持高效..

谢谢

【问题讨论】:

标签: c++ performance sorting criteria


【解决方案1】:

您可以使用第三个参数定义每次运行排序算法时使用的比较函数:

template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
          StrictWeakOrdering comp);

一个简单的例子:

struct person {
   std::string name;
   int age;
};
bool sort_by_name( const person & lhs, const person & rhs )
{
   return lhs.name < rhs.name;
}
bool sort_by_age( const person & lhs, const person & rhs )
{
   return lhs.age < rhs.age;
}
int main() {
   std::vector<person> people;
   // fill in the vector
   std::sort( people.begin(), people.end(), sort_by_name );
   std::sort( people.begin(), people.end(), sort_by_age );
}

【讨论】:

【解决方案2】:

std::sort 有 2 个版本,第 2 个版本接受比较函子:

template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
          StrictWeakOrdering comp);
//--------^^^^^^^^^^^^^^^^^^^^^^^

例如:

bool isLessThan(const MyStruct& first, const MyStruct& second) {
   if (first.name < second.name) return true;
   else if (first.name == second.name) {
      if (first.date > second.date) return true;
      // etc.
   }
   return false;
}

...

sort(v.begin(), v.end(), isLessThan);

另见http://www.cplusplus.com/reference/algorithm/sort/

此变体仍然使用相同的快速排序算法,因此平均为 O(n log n)。

【讨论】:

    【解决方案3】:

    std::sort 有两个版本,第一个简单地接受迭代器并使用对象的 operatorStrictWeakOrdering 概念的类作为比较器。比较器对象(或函数)应该可以用两个参数调用,其中每个参数都是指定的类型,如果第一个参数小于第二个参数,它应该返回 true。例如:

    bool mycomarator(const T& a, const T&b); // 如果 a

    类 MyComparator { 上市: bool operator()(const T& a, const T& b)const; // 如果 a

    【讨论】:

      【解决方案4】:

      为了完整起见,这里是一个使用 c++0x lambda 函数的示例:

      std::vector<Person> v;
      std::sort(v.begin(), v.end(), [](Person a, Person b) { return a.name_ < b.name_; });
      ...
      std::sort(v.begin(), v.end(), [](Person a, Person b) { return a.address_ < b.address_; });
      

      【讨论】:

        【解决方案5】:

        Boost.Bind 允许在简单的情况下就地定义比较函数:

        #include <iostream>
        #include <algorithm>
        
        #include <boost/foreach.hpp>
        #include <boost/format.hpp>
        #include <boost/bind.hpp>
        
        #define P(a) do {                                                       \
            BOOST_FOREACH (Struct s, a)                                         \
              std::cout << boost::format("(%d %c) ") % s.i % s.c;               \
            std::cout << std::endl;                                             \
          } while(0)
        
        namespace {
          struct Struct { int i; char c; };
        }
        
        int main() {
          using boost::bind;
        
          Struct a[] = { 1, 'z', 2, 'a' }; P(a);
          const int N = sizeof(a) / sizeof(*a);
        
          std::sort(a, a + N, bind(&Struct::i, _1) > bind(&Struct::i, _2));  P(a);
          std::sort(a, a + N, bind(&Struct::c, _1) > bind(&Struct::c, _2));  P(a);
        }
        

        输出:

        (1 z) (2 a) 
        (2 a) (1 z) 
        (1 z) (2 a) 
        

        【讨论】:

          猜你喜欢
          • 2010-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-01
          • 1970-01-01
          相关资源
          最近更新 更多