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.
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.
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.
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.
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.
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.
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.
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.
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 tuple
s. The return type is the boolean result of your comparison. Since tuple
s 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;
});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With