How to sort array of pair <int, pair <int, int> >, by first element, but descending order?

Viewed 351

I want to sort an array containing pair <int, pair <int, int> >, by the first value, in descending order.

I had

pair <int, pair<int, int> > adj[10];

which had values in it, unsorted.

When I used

sort(adj, adj + 10);

it would sort the array based on the adj[i].first value, in ascending order.

However, when I tried sorting in descending order

sort(adj, adj + 10, greater<int>());

It wasn't letting me.

Is there other way to sort by descending order?

4 Answers

You could write:

std::sort(std::begin(adj), std::end(adj), 
          std::greater<std::pair<int, std::pair<int, int>>>{});

In , you could simplify this to:

std::sort(std::begin(adj), std::end(adj), std::greater<>{});

In , you could simply it a little more:

std::sort(std::begin(adj), std::end(adj), std::greater{});

In , you could simplify this much further:

std::ranges::sort(adj, std::greater{});

You can write a custom predicate using a lambda.

std::sort(std::begin(adj),
          std::end(adj),
          [](auto const& lhs, auto const& rhs)
{
    return lhs.first > rhs.first;
});

Note that the above predicate only considers the first element. You could expand that to look at the further elements if you wanted more complex sorting.

A simple way is to use a lambda expression as for example

#include <utility>
#include <iterator>
#include <algorithm>

//...

std::sort( std::begin( adj ), std::end( adj ),
           []( const auto &a, const auto &b )
           {
               return b.first < a.first;
           } );

Here is a demonstrative program.

#include <iostream>
#include <utility>
#include <functional>
#include <iterator>
#include <algorithm>

int main() 
{
    const size_t N = 3;
    
    std::pair <int, std::pair<int, int> > adj[N] =
    {
        { 1, { 1, 2 } }, { 1, { 2, 1 } }, { 2, { 1, 1 } }
    };;
    
    std::sort( std::begin( adj ), std::end( adj ),
               []( const auto &a, const auto &b )
               {
                    return b.first < a.first;
               } );
    
    for ( const auto &p : adj )
    {
        std::cout << " { " << p.first << ", { " 
                           << p.second.first << ", " 
                           << p.second.second << " } } ";
    }
    
    std::cout << '\n';
    
    return 0;
}

The program output is

{ 2, { 1, 1 } }  { 1, { 1, 2 } }  { 1, { 2, 1 } } 

As you can see from the output if two elements of the array have equal values of the first member of an object of the type std::pair then values of the second member are not taken into account and can be unordered.

Another approach is to use the expression std::gretar<>(). That is to use the default template argument for the functional object std::greater. Here is a demonstrative program.

#include <iostream>
#include <utility>
#include <functional>
#include <iterator>
#include <algorithm>

int main() 
{
    const size_t N = 3;
    
    std::pair <int, std::pair<int, int> > adj[N] =
    {
        { 1, { 1, 2 } }, { 1, { 2, 1 } }, { 2, { 1, 1 } }
    };;
    
    std::sort( std::begin( adj ), std::end( adj ), std::greater<>() );
    
    for ( const auto &p : adj )
    {
        std::cout << " { " << p.first << ", { " 
                           << p.second.first << ", " 
                           << p.second.second << " } } ";
    }
    
    std::cout << '\n';
    
    return 0;
}

The program output is

{ 2, { 1, 1 } }  { 1, { 2, 1 } }  { 1, { 1, 2 } } 

In this case if two elements have an equal value of the first member then they are ordered according to values of the second member.

If your compiler does not support the C++ 14 Standard then the same effect of using std::greater<> you can achieve using the following lambda expression.

std::sort( std::begin( adj ), std::end( adj ),
           []( const auto &a, const auto &b )
           {
                return b < a;
           } );

since you are using c++14 here is how: sort using std::greater<>{}

std::pair <int, std::pair<int, int> > adj[3];
adj[0]=std::make_pair(10,std::make_pair(0,0));
adj[1]=std::make_pair(1,std::make_pair(0,0));
adj[2]=std::make_pair(7,std::make_pair(0,0));

std::sort(adj, adj+3, std::greater<>{});

std::cout << "Sorted \n";
for (auto x=0; x<3;++x)
    std::cout << "x: " << adj[x].first << "\n";

return 0;
Related