Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Construct a vector of Tuples and Sort them like Pair?

Suppose, I have several integer elements like this:

(3 9 1), (1 5 2), (2 8 3), (1 4 4), (1 6 5), (1 5 6)

Now I want to sort the elements like vector of pairs are sorted. Only difference is that instead of 2 keys we have 3 keys here. After sorting the elements will look like:

(1 4 4), (1 5 2), (1 5 6), (1 6 5), (2 8 3), (3 9 1)

Is there any STL or other techniques to achieve this? I found out about Tuples but having some problems to understand this well.
Can you guys help me in any way please? May be by providing useful links or Explaining the process.

like image 228
Hafiz Al Masud Ovi Avatar asked Apr 30 '18 17:04

Hafiz Al Masud Ovi


People also ask

How do you sort a vector tuple?

Case 1 : Sorting the vector elements on the basis of first element of tuples in ascending order. This type of sorting can be achieved using simple “ sort() ” function. By default the sort function sorts the vector elements on basis of first element of tuples.

How do you make a vector tuple in C++?

1. make_tuple(): make_tuple() is used to assign tuple with values. The values passed should be in order with the values declared in the tuple. 2.

Can you sort a vector of pairs?

We can sort the vector of pairs using the generic sorting algorithm provided by STL. The std::sort function takes two iterators of the range to be sorted, and it rearranges the elements in non-descending order by default. In the case of pairs, the vector is sorted by the first element of each pair.

How to sort the elements of vector on the basis of tuples?

By default the sort function sorts the vector elements on basis of first element of tuples. Case 2 : Sorting the vector elements on the basis of second element of tuples in ascending order. There are instances when we require to sort the elements of vector on the basis of second elements of tuples.

How to sort the elements of tuples in Python?

The elements of tuples are initialized as arguments in order in which they will be accessed. Case 1 : Sorting the vector elements on the basis of first element of tuples in ascending order. This type of sorting can be achieved using simple “ sort () ” function.

What is vector of tuple in C++?

Sorting of Vector of Tuple in C++ (Ascending Order) What is Vector of Tuple? A tuple is an object that can hold a number of elements and a vector containing multiple number of such tuple is called a vector of tuple. The elements can be of different data types.

How to sort a vector of pairs?

A pair is a container which stores two values mapped to each other, and a vector containing multiple number of such pairs is called a vector of pairs. Case 1 : Sorting the vector elements on the basis of first element of pairs in ascending order. This type of sorting can be achieved using simple “ sort () ” function.


2 Answers

A vector of tuple can be sorted using nothing but STL if you want.

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

int main(int argc, char * argv[]){

    std::vector< std::tuple<int, int, int> > myVec;

    myVec.emplace_back(3, 9, 1);
    myVec.emplace_back(1, 5, 2);
    myVec.emplace_back(2, 8, 3);
    myVec.emplace_back(1, 4, 4);
    myVec.emplace_back(1, 6, 5);
    myVec.emplace_back(1, 5, 6);

    std::sort(myVec.begin(), myVec.end());

    for (auto i : myVec){
        std::cout << std::get<0>(i) << ", " << std::get<1>(i) << ", " << std::get<2>(i) << '\n';
    }

    return 0;
}

This is the example from here just modified with your values.

How it works is a new tuple is constructed with emplace_back and added to the end of the vector. You could use push_back(std::make_tuple(... if you want but that seems overly complicated. Then you sort the vector as you would any other vector. The default behavior of sort is ascending. You can change the behavior of sort by adding you own comp. The arguments of your comparing function will be 2 tuples. The return type is the boolean result of your comparison. Since tuples have all the comparisons (<,>, <=,etc) already, you don't need to redefine them. You can use this to compare dissimilar things as well, it just gets more complicated.

bool myFunction(const std::tuple<int, int, int> &i, const std::tuple<int, int, int> &j) {
    return i > j;
}

....
std::sort(myVec.begin(), myVec.end(), myFunction);
....

And this will sort the vector in descending order. You can replace myFunction with a lambda as well.

std::sort(myVec.begin(), myVec.end(), [](const std::tuple<int, int, int> &i, const std::tuple<int, int, int> &j) {
    return i > j;
});
like image 108
Matt Avatar answered Oct 09 '22 18:10

Matt


I propose two solutions: the first using a custom structure using a custom < operator that uses std::tie to compare the three integers in order, and the second using std::tuple.

#include <iostream>
#include <set>
#include <vector>

struct three_integers {
  int a, b, c;
  bool operator<(const three_integers &other) const {
    return std::tie(a, b, c) < std::tie(other.a, other.b, other.c);
  }
};

int main(int argc, char *argv[]) {

  // 1st solution using a custom structure
  // std::set containers are always ordered according to the < operator
  std::set<three_integers> sorted_set = {{3, 9, 1}, {1, 5, 2}, {2, 8, 3},
                                         {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  std::cout << "Sorted set:\n";
  for (auto &element : sorted_set) {
    std::cout << "(" << element.a << " " << element.b << " " << element.c << ")"
              << std::endl;
  }

  std::vector<three_integers> sorted_vector = {{3, 9, 1}, {1, 5, 2}, {2, 8, 3},
                                               {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  // std::vector is not ordered, so we call std::sort on it to make it just like
  // std::set, it will use our custom < operator
  std::sort(sorted_vector.begin(), sorted_vector.end());

  std::cout << "Sorted vector:\n";
  for (auto &element : sorted_vector) {
    std::cout << "(" << element.a << " " << element.b << " " << element.c << ")"
              << std::endl;
  }

  // 2nd solution using tuples
  std::vector<std::tuple<int, int, int>> sorted_vector_tuple = {
      {3, 9, 1}, {1, 5, 2}, {2, 8, 3}, {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  std::sort(sorted_vector_tuple.begin(), sorted_vector_tuple.end());

  std::cout << "Sorted vector of tuples:\n";
  for (auto &element : sorted_vector_tuple) {
    std::cout << "(" << std::get<0>(element) << " " << std::get<1>(element)
              << " " << std::get<2>(element) << ")" << std::endl;
  }

  return 0;
}

Output

Sorted set:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)
Sorted vector:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)
Sorted vector of tuples:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)

I recommend you to read the std::sort documentation.

like image 24
Henrique Jung Avatar answered Oct 09 '22 19:10

Henrique Jung