【问题标题】: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)