Sorting a vector of pairs
Solution 1
In C++, you can have custom comparator functions that specify how to decide whether one element goes before another when sorting. In your case, given 2 pairs, you want the one with the lower value for the first element to go before the other one. You can write a comparator function like so:
// This function returns true if the first pair is "less"
// than the second one according to some metric
// In this case, we say the first pair is "less" if the first element of the first pair
// is less than the first element of the second pair
bool pairCompare(const std::pair<double, Processor*>& firstElem, const std::pair<double, Processor*>& secondElem) {
return firstElem.first < secondElem.first;
}
Now, pass this function into your sort method:
//The sort function will use your custom comparator function
std::sort(baryProc.begin(), baryProc.end(), pairCompare);
Solution 2
#include <algorithm>
int main(){
std::vector<std::pair<double,Processor*>> baryProc;
std::sort(baryProc.begin(),baryProc.end());
}
Note that you do not need a custom comparator because the default comparator of pair does the thing you want. It first compares by the first element and if they are identical, it compares the second element in the pair.
user2633791
Updated on March 07, 2020Comments
-
user2633791 about 4 years
I have a question about sorting a vector of pairs:
std::vector<std::pair<double,Processor*>> baryProc;
this vector is already filled up with the pairs. Now I wanted to sort the pairs inside the vector based on the double value inside the pair
EXAMPLE:
suppose I have 3 pairs inside the vector. pair1 is at front and pair 3 is at end. pair2 is in the middle:
pair1(1, proc1) pair2(3, proc2) pair3(2.5, proc3)
now i want to sort the pairs based on the double value. So that the order inside the vector is:
pair1(1, proc1) pair3(2.5, proc3) pair2(3, proc2)
How could I do this? I am quite stuck.
-
WhozCraig over 10 yearsThis will work if the
double
values are guaranteed unique (effectively a "set"). But without such a guarantee (by force if needed) you need to write a comparator. The default comparator forpair
typically does areturn (a.first < b.first || (a.first == b.first && a.second < b.second;
The latter is the pointer-comparison that will bite you with non-unique values forfirst
. -
WhozCraig over 10 years+1 a good example of eliminating the
.second
comparison from the normal less-operator ofstd::pair
. I would prefer a functor for this (more likely to inline), but a functional solution works none-the-less. -
Hossein Nasr over 10 yearswe have no condition to help us what to do when the first elements are the same. so what happen if we use default comparator?
-
Kevin over 10 yearsWhy did you specify
std::vector
andstd::pair
but notstd::sort
? If you did that, you could get rid of theusing namespace std
bit entirely. -
WhozCraig over 10 years@hoosssein See my comment. the default less-than operator (invoked by
std::less<>
forstd::pair<>
can, and will, hit both values if needed (typically as i described). The solution is to provide a custom comparator, as maditya has demonstrated. -
Hossein Nasr over 10 yearsno reason. i just copy variable declaration form question. thanks for your note.
-
WhozCraig over 10 yearsSo long as you understand that for identical
double
values the less-than state now rests on comparing two pointers, which is most-assuredly what you do NOT want to happen (it rarely is, in fact, so). -
Hossein Nasr over 10 yearsso, as I understand, this my cause inconsistency in sorting? or you just worry about simple comparison between 2 pointer that cause at most 5 clock of CPU?
-
user2633791 over 10 yearsThanks for this good explanation. i guess the standard comparator will work fine. Would standart oparator sort right if double values are often the same? e.g.: (1,proc1), (1,proc2), (2,proc3), (3,proc4), (3,proc5),....
-
maditya over 10 years@user2633791 What you're asking is whether the sort is stable. A sorting algorithm is stable if two elements with the same value remain in the same order relative to one another at the end of the sort as they were at the beginning. The default sort algorithm is not stable, but STL provides a stable sort which should suit your purposes.
-
Blastfurnace over 10 yearsUnless two pointers point into or one-past-the-end of the same array the comparison is undefined. If the user wants to order the pairs by the first element then they should only compare the first elements in this case.
-
user2633791 over 10 yearswhy does the standard comparator here take the double values of the pair?
-
juanchopanza over 10 years@user2633791 the standard comparator compares lexicographically, using
first
first andsecond
second. Why? Because it makes sense. -
Hossein Nasr over 10 yearsas is said, at first it use first element(
pair.first
) then it use second element in pare (pair.second
) to compare to pairs of any type. -
user2633791 over 10 yearsthanks. works fine now with standard comparator if you use my own comparator my compiler says: this function call misses the list of arguments this pointers will ruin me :)
-
user2633791 over 10 years@maditya any idea why my compiler would say so? Missing arguments for this function call. use "&pairCompare" instead of "pairCompare" to get a pointer on this member. but doing so doesnt help
-
maditya over 10 years@user2633791 There were extra '>' characters in the arguments to the function, I've removed them now. I think that was probably the problem. (Should be
std::pair<double, Processor*>
rather thanstd::pair<double, Processor*>>
) -
user2633791 over 10 yearsyeah i noticed this before... unfortunately not the mistake :(
-
maditya over 10 years@user2633791 Not sure then sorry ... it compiles for me