Сортировка вектора по убыванию - PullRequest
286 голосов
/ 27 января 2012

Должен ли я использовать

std::sort(numbers.begin(), numbers.end(), std::greater<int>());

или

std::sort(numbers.rbegin(), numbers.rend());   // note: reverse iterators

отсортировать вектор в порядке убывания? Есть ли какие-либо преимущества или недостатки с одним или другим подходом?

Ответы [ 10 ]

106 голосов
/ 29 апреля 2013

На самом деле, первая - плохая идея. Используйте либо второй , либо этот:

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.

62 голосов
/ 27 января 2012

Используйте первое:

std::sort(numbers.begin(), numbers.end(), std::greater<int>());

Это ясно из того, что происходит - меньше шансов неправильно прочитать rbegin как begin, даже с комментарием. Это ясно и читаемо, что именно то, что вы хотите.

Кроме того, второй может быть менее эффективным, чем первый, учитывая природу обратных итераторов, хотя вам, конечно, придется профилировать его.

53 голосов
/ 11 июня 2016

С помощью c ++ 14 вы можете сделать это:

std::sort(numbers.begin(), numbers.end(), std::greater<>());
25 голосов
/ 10 сентября 2015

Как насчет этого?

std::sort(numbers.begin(), numbers.end());
std::reverse(numbers.begin(), numbers.end());
20 голосов
/ 31 июля 2016

Вместо функтора, как предложил Мерадад, вы можете использовать лямбда-функцию.

sort(numbers.begin(), numbers.end(), [](const int a, const int b) {return a > b; });
15 голосов
/ 27 января 2012

Согласно моей машине, сортировка вектора long long [1..3000000] с использованием первого метода занимает около 4 секунд, в то время как использование второго занимает примерно вдвое больше времени.Это говорит о чем-то, очевидно, но я тоже не понимаю почему.Просто подумайте, что это было бы полезно.

То же самое сообщалось здесь .

Как сказал Xeo, с -O3 они используют примерно одинаковое время для финиша.

10 голосов
/ 06 июня 2017

Первый подход относится к:

    std::sort(numbers.begin(), numbers.end(), std::greater<>());

Вы можете использовать первый подход, потому что получаете больше эффективности, чем второй.
Сложность времени первого подхода меньше, чем второго.

6 голосов
/ 22 марта 2017
bool comp(int i, int j) { return i > j; }
sort(numbers.begin(), numbers.end(), comp);
1 голос
/ 29 апреля 2017

Я не думаю, что вы должны использовать любой из методов в вопросе, поскольку они оба сбивают с толку, а второй является хрупким, как предлагает Мерадад.как стандартная библиотечная функция и проясняет ее назначение:

#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>());
}
1 голос
/ 13 августа 2016

Вы можете использовать первый или попробовать приведенный ниже код, который одинаково эффективен

sort(a, a+n, greater<int>());
...