[英]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
時,你的代碼不會默默地破壞。
使用第一個:
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
這是明確的是怎么回事的-誤讀的機會較少rbegin
作為begin
,即使有意見。 它清晰可讀,正是您想要的。
此外,第二個可能效率低於第一個給定反向迭代器的性質,盡管你必須對其進行分析以確定。
使用c ++ 14,您可以這樣做:
std::sort(numbers.begin(), numbers.end(), std::greater<>());
那這個呢?
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<>());
您可以使用第一種方法,因為它比第二種方法獲得更高的效率。
第一種方法的時間復雜度小於第二種方法。
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>());
}
使用任何。 它們幾乎是一樣的。
像往常一樣,有利有弊。
使用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
demo std::reverse_iterator
演示
時間是一樣的。 Valgrind報告了相同數量的緩存未命中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.