按降序对矢量进行排序
Sorting a vector in descending order
我应该使用吗
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
或
std::sort(numbers.rbegin(), numbers.rend()); // note: reverse iterators
按降序对向量进行排序?一种或另一种方法有什么好处或缺点吗?
实际上,第一个是个坏主意。使用第二个,或者这个:
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
时,您的代码就不会静默地中断。
使用c++14,您可以执行以下操作:
std::sort(numbers.begin(), numbers.end(), std::greater<>());
使用第一个:
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
它清楚地表明了正在发生的事情——即使有评论,也不太可能将rbegin
误读为begin
。它清晰易读,正是你想要的。
此外,考虑到反向迭代器的性质,第二个迭代器可能不如第一个迭代程序有效,尽管您必须对其进行分析才能确定。
这个怎么样?
std::sort(numbers.begin(), numbers.end());
std::reverse(numbers.begin(), numbers.end());
您可以使用Lambda函数来代替Mehrdad提出的函子。
sort(numbers.begin(), numbers.end(), [](const int a, const int b) {return a > b; });
根据我的机器,使用第一种方法对[1..3000000]的long long
向量进行排序大约需要4秒,而使用第二种方法大约需要两倍的时间。很明显,这说明了一些问题,但我也不明白为什么。我想这会有帮助的。
这里也报道了同样的事情。
正如Xeo所说,对于-O3
,他们使用大约相同的时间来完成。
第一种方法是:
std::sort(numbers.begin(), numbers.end(), std::greater<>());
你可以使用第一种方法,因为它比第二种方法更有效率
第一种方法的时间复杂性小于第二种方法。
TL;DR
使用任意。它们几乎是一样的。
无聊的答案
和往常一样,有优点也有缺点。
使用std::reverse_iterator
:
- 当您对自定义类型进行排序并且不想实现
operator>()
- 当您懒得键入
std::greater<int>()
时
当:时使用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
std::greater
演示std::reverse_iterator
演示
时间是一样的。Valgrind报告了相同数量的缓存未命中。
bool comp(int i, int j) { return i > j; }
sort(numbers.begin(), numbers.end(), comp);
您可以使用第一个,也可以尝试下面的代码,它同样有效
sort(&a[0], &a[n], greater<int>());
我认为你不应该使用问题中的任何一种方法,因为它们都令人困惑,而第二种方法正如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>());
}
- 我正在尝试按降序对地图进行排序,但没有得到预期的结果?
- 如何在 c++ 中根据第二个元素按降序对列表进行排序
- 如何按矩阵行的总和降序对矩阵进行排序 C++.
- 插入按降序排序
- 如何使用cpp编写选择排序算法以降序对元素列表进行排序?
- 我怎么不能按课程代码的降序对数字进行排序
- 如何使用布尔函数按降序对数组进行排序?
- 如何按降序排序?
- 数组将排序排序为降序而不是升序
- 如何按降序对标准数组进行排序 - C++ 11.
- 按降序C 排序矢量
- 使用QuickSort算法以降序排序向量
- 偶数升序排序,奇数降序排序
- 按类向量的降序排序
- 按降序排序的最佳方式
- 快速排序在对降序-升序数据进行排序时的奇怪行为
- C++使用单独的函数按降序对数组进行排序
- 按降序对双链接列表进行排序
- 对结构、降序或升序的向量进行排序:C++
- 桶排序降序