0

So I have a vector say:

vector<pair<pair<int,int>,pair<int,int>>>

having elements as:

[(11,13),(2,1)], [(5,6),(1,2)] ,[(9,10),(1,3)] ,[(5,8),(3,4)] , 
[(12,14),(2,7)].

After sorting (i.e. primarily with respect to the first value of the second pair and secondarily with respect to second value of the first pair... So after sorting the output should look like this:

[(5,6),(1,2)] ,[(9,10),(1,3)] ,[(11,13),(2,1)] ,[(12,14),(2,7)] ,
[(5,6),(3,4)]

I had read that we can sort using first or the second value if a vector contains a pair , but how to proceed if a vector contains nested pairs....

Edit: Tried to implement it as shown here :https://www.geeksforgeeks.org/sorting-vector-of-pairs-in-c-set-1-sort-by-first-and-second/

here's the code:

bool sortbysecfirst(const pair<pair<int,int>,pair<int,int>> &a,const pair<pair<int,int>,pair<int,int>> &b) { 
    return (a.second.first < b.second.first); 
}

bool sortbyfirstsec(const pair<pair<int,int>,pair<int,int>> &a,const pair<pair<int,int>,pair<int,int>> &b) { 
    return (a.first.second < b.first.second); 
}

sort(arr.begin(),arr.end(),sortbysecfirst);
sort(arr.begin(),arr.end(),sortbyfirstsec);

Now for the following pairs :

[(11,13)(2,1)],[(5,6)(1,2)],[(9,10)(1,3)],[(5,8)(3,4)],[(6,7)(1,5)],
 [(10,15)(5,6)],[(12,14)(2,7)],[(1,2),(1,8)],

The answer should be:

[1, 2, 1, 8], [5, 6, 1, 2], [6, 7, 1, 5],  [9, 10, 1, 3], [11, 13, 2, 1], [12, 14, 2, 7],[5, 8, 3, 4], [10, 15, 5, 6], 

But i am getting this as an answer:

[1, 2, 1, 8], [5, 6, 1, 2], [6, 7, 1, 5], [5, 8, 3, 4], [9, 10, 1, 3], [11, 13, 2, 1], [12, 14, 2, 7], [10, 15, 5, 6],
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

1 Answers1

2

You can use standard function std::tie declared in header <tuple> .

Here you are.

#include <iostream>
#include <utility>
#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
    std::vector<std::pair<std::pair<int,int>, std::pair<int,int>>> v =
    {
        { { 11, 13 }, { 2, 1 } }, { { 5, 6 }, { 1, 2 } }, { { 9, 10 }, { 1, 3 } } ,
        { { 5, 8 }, { 3, 4 } }, { { 12, 14 }, { 2, 7 } }
    };

    for ( const auto &p : v )
    {
        std::cout << "{ ";          
        std::cout << "{ " << p.first.first << ", " << p.first.second << " }, ";
        std::cout << "{ " << p.second.first << ", " << p.second.second << " } ";
        std::cout << "}, "; 
    }

    std::cout << '\n';

    std::sort( std::begin( v ), std::end( v ),
               []( const auto &p1, const auto &p2 )
               {
                    return std::tie( p1.second.first, p1.first.second ) < 
                           std::tie( p2.second.first, p2.first.second );    
               } );

    for ( const auto &p : v )
    {
        std::cout << "{ ";          
        std::cout << "{ " << p.first.first << ", " << p.first.second << " }, ";
        std::cout << "{ " << p.second.first << ", " << p.second.second << " } ";
        std::cout << "}, "; 
    }

    std::cout << '\n';
}

The program output is

{ { 11, 13 }, { 2, 1 } }, { { 5, 6 }, { 1, 2 } }, { { 9, 10 }, { 1, 3 } }, { { 5, 8 }, { 3, 4 } }, { { 12, 14 }, { 2, 7 } }, 
{ { 5, 6 }, { 1, 2 } }, { { 9, 10 }, { 1, 3 } }, { { 11, 13 }, { 2, 1 } }, { { 12, 14 }, { 2, 7 } }, { { 5, 8 }, { 3, 4 } }, 

As for this code snippet shown by you

bool sortbysecfirst(const pair<pair<int,int>,pair<int,int>> &a,const pair<pair<int,int>,pair<int,int>> &b) { 
    return (a.second.first < b.second.first); 
}

bool sortbyfirstsec(const pair<pair<int,int>,pair<int,int>> &a,const pair<pair<int,int>,pair<int,int>> &b) { 
    return (a.first.second < b.first.second); 
}

sort(arr.begin(),arr.end(),sortbysecfirst);
sort(arr.begin(),arr.end(),sortbyfirstsec);

then each call of std::sort sorts the vector anew destroying the order set by the previous call.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335