我应该用
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
或
std::sort(numbers.rbegin(), numbers.rend()); // note: reverse iterators
按降序对向量排序?这两种方法有什么优点或缺点吗?
使用第一个:
它明确了正在发生的事情——即使带有注释,将rbegin误读为begin的可能性也更小。它清晰易读,这正是你想要的。
rbegin
begin
另外,考虑到反向迭代器的性质,第二个迭代器的效率可能比第一个要低,尽管您必须对它进行分析以确定。
根据我的机器,排序long long向量[1..使用第一种方法大约需要4秒,而使用第二种方法大约需要两倍的时间。这显然说明了一些问题,但我也不明白为什么。我只是觉得这会有帮助。
long long
同样的事情报告在这里。
正如Xeo所说,使用-O3他们使用相同的时间来完成。
-O3
事实上,第一个不是个好主意。使用第二个,或者这个:
struct greater { template<class T> bool operator()(T const &a, T const &b) const { return a > b; } }; std::sort(numbers.begin(), numbers.end(), greater());
这样,当有人决定numbers应该保存long或long long而不是int时,您的代码不会无声地崩溃。
numbers
long
int
这个呢?
std::sort(numbers.begin(), numbers.end()); std::reverse(numbers.begin(), numbers.end());
用c++14你可以这样做:
std::sort(numbers.begin(), numbers.end(), std::greater<>());
你可以使用Lambda函数,而不是像Mehrdad建议的那样使用函子。
sort(numbers.begin(), numbers.end(), [](const int a, const int b) {return a > b; });
您可以使用第一个方法,也可以尝试下面同样有效的代码
sort(&a[0], &a[n], greater<int>());
bool comp(int i, int j) { return i > j; } sort(numbers.begin(), numbers.end(), comp);
我认为你不应该使用问题中的任何一种方法,因为它们都令人困惑,第二种方法正如Mehrdad所说的那样是脆弱的。
我建议使用以下方法,因为它看起来像一个标准的库函数,而且它的意图很明确:
#include <iterator> template <class RandomIt> void reverse_sort(RandomIt first, RandomIt last) { std::sort(first, last, std::greater<typename std::iterator_traits<RandomIt>::value_type>()); }
第一种方法是指:
使用任何。它们几乎一样。
和往常一样,有利有弊。
使用std::reverse_iterator:
std::reverse_iterator
operator>()
std::greater<int>()
在以下情况使用std::greater:
std::greater
至于性能,两种方法的效率是一样的。我尝试了以下基准:
#include <algorithm> #include <chrono> #include <iostream> #include <fstream> #include <vector> using namespace std::chrono; /* 64 Megabytes. */ #define VECTOR_SIZE (((1 << 20) * 64) / sizeof(int)) /* Number of elements to sort. */ #define SORT_SIZE 100000 int main(int argc, char **argv) { std::vector<int> vec; vec.resize(VECTOR_SIZE); /* We generate more data here, so the first SORT_SIZE elements are evicted from the cache. */ std::ifstream urandom("/dev/urandom", std::ios::in | std::ifstream::binary); urandom.read((char*)vec.data(), vec.size() * sizeof(int)); urandom.close(); auto start = steady_clock::now(); #if USE_REVERSE_ITER auto it_rbegin = vec.rend() - SORT_SIZE; std::sort(it_rbegin, vec.rend()); #else auto it_end = vec.begin() + SORT_SIZE; std::sort(vec.begin(), it_end, std::greater<int>()); #endif auto stop = steady_clock::now(); std::cout << "Sorting time: " << duration_cast<microseconds>(stop - start).count() << "us" << std::endl; return 0; }
使用以下命令行:
g++ -g -DUSE_REVERSE_ITER=0 -std=c++11 -O3 main.cpp \ && valgrind --cachegrind-out-file=cachegrind.out --tool=cachegrind ./a.out \ && cg_annotate cachegrind.out g++ -g -DUSE_REVERSE_ITER=1 -std=c++11 -O3 main.cpp \ && valgrind --cachegrind-out-file=cachegrind.out --tool=cachegrind ./a.out \ && cg_annotate cachegrind.out
< kbd > std::greater演示 std::reverse_iterator演示 < / kbd >
时间是一样的。Valgrind报告了相同数量的缓存丢失。