Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does std::sort work for list of pairs?

Why does this:

#include <iostream>
#include <string>
#include <vector>                                                             
#include <algorithm>

using namespace std;

vector<pair<int, string>> list;

int main() {
    int one = 1, two = 2, three =3, five =5, six = 6;
    string bla = "bla";

    list.push_back( pair<int, string>(two, bla));
    list.push_back( pair<int, string>(one, bla));
    list.push_back( pair<int, string>(two, bla));
    list.push_back( pair<int, string>(six, bla));
    list.push_back( pair<int, string>(five, bla));

    sort(list.begin(), list.end());

    for(auto item : list) {
        cout << item.first << endl;
    }
}

work as intended? output is:

1
2
2
5
6

How std::sort gets how to sort my int-string pairs? How to make it do so for some class of mine as pair first? Is there a way to sort by second using std::sort?

like image 523
DuckQueen Avatar asked May 22 '14 20:05

DuckQueen


People also ask

Can you sort pairs C++?

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. By default the sort function sorts the vector elements on basis of first element of pairs.

Can you use std::sort with a list?

std::sort requires random access iterators and so cannot be used with list .

How does std::sort Work C++?

The std::sort is a sorting function that uses the Introsort algorithm and have the complexity of O(N log(N)) where N= std::distance(first, last) since C++11 and the order of equal elements is not guaranteed to be preserved[3]. The gcc-libstdc++ also uses Introsort algorithm.

What does std::sort do?

std::sort() is a built-in function in C++'s Standard Template Library. The function takes in a beginning iterator, an ending iterator, and (by default) sorts the iterable in ascending order. The function can also​ be used for custom sorting by passing in a comparator function that returns a boolean.


2 Answers

Since operator< is defined for std::pair and it is based on std::pair::first and then std::pair::second (lexicographical), so your code is working as the standard. To sort it based on the second part of the std::pair you can try this:

std::sort(list.begin(), list.end(), [](const std::pair<int, string> &x,
                                       const std::pair<int, string> &y)
{
    return x.second < y.second;
});
like image 151
masoud Avatar answered Oct 07 '22 21:10

masoud


There is one "obvious" ordering of product types induced by the respective orderings of the components, and that is lexicographical order:

(a, b) < (c, d)  <=>  a < c || (a == c && b < d)

This is the ordering used by operator< of std::pair. In your example, since all the first components are distinct, the ordering happens to be equal to the ordering of the first component. It gets more interesting if you have multiple occurences of the same value in the first component, in which the second component is used to break ties.

How to make it do so for some class of mine as pair first?

You just have to define operator< for your type. But keep in mind that the second component will be considered if necessary and you might not want that overhead.

Is there a way to sort by second using std::sort?

Yes, just use a custom comparator functor. You can always do that if you don't want to use the default operator< for sorting.

like image 44
Niklas B. Avatar answered Oct 07 '22 22:10

Niklas B.