Search code examples
c++algorithmstlcomparisonstable-sort

Difference between Iterator and reverse iterator


what is difference between the following two code snippets.

vector<int> a;
// initialization code
sort( a.rbegin(), a.rend() );

and

vector<int> a;
// same initialization as above
sort(a.begin(), a.end(), comp);

where comp is a boolean function given below

bool comp( int i, int j)
{
    return i>j;
}

To illustrate, the following code gives WA while this code gives AC for SPOJ problem XMAX. The only difference between AC and WA is the version of sort() used.


Solution

  • The two function calls do NOT give the same answer because std::sort is not a stable algorithm, i.e. it does not keep identical elements in their relative ordenings. Below an example where elements of std::pair<int, int> are sorted on their first element. Sorting and sorting in reverse order with the reversed comparison function does not yield identical sequences. Doing the same with std::stable_sort does yield identical results.

    #include <algorithm>
    #include <iostream>
    #include <ios>
    #include <vector>
    
    int main()
    {
        typedef std::pair<int, int> Element;
        std::vector<Element> v;
    
        v.push_back( Element(1,1) );
        v.push_back( Element(-1,1) );
        v.push_back( Element(1,2) );
        v.push_back( Element(-1,2) );
        v.push_back( Element(1,3) );
        v.push_back( Element(-1,3) );
        v.push_back( Element(1,4) );
        v.push_back( Element(-1,4) );
        v.push_back( Element(1,5) );
        v.push_back( Element(-1,5) );
        v.push_back( Element(1,6) );
        v.push_back( Element(-1,6) );
        v.push_back( Element(1,16) );
        v.push_back( Element(-1,16) );
        v.push_back( Element(1,22) );
        v.push_back( Element(-1,22) );
        v.push_back( Element(1,33) );
        v.push_back( Element(-1,33) );
        v.push_back( Element(1,44) );
        v.push_back( Element(-1,44) );
        v.push_back( Element(1,55) );
        v.push_back( Element(-1,55) );
        v.push_back( Element(1,66) );
        v.push_back( Element(-1,66) );
    
        for (auto it = v.begin(); it != v.end(); ++it) {
            std::cout << "(" << it->first << "," << it->second << ")" << " ";
        }
        std::cout << "\n";
    
        auto w1 = v;
        std::sort(w1.begin(), w1.end(), [](Element const& e1, Element const& e2){ 
           return e1.first < e2. first;
        });
        auto w2 = v;
        std::sort(w2.rbegin(), w2.rend(), [](Element const& e1, Element const& e2) {
           return e1.first > e2.first;
        });
        std::cout << std::boolalpha << std::equal(w1.begin(), w1.end(), w2.begin()) << "\n";
    
        auto w3 = v;
        std::stable_sort(w3.begin(), w3.end(), [](Element const& e1, Element const& e2){ 
           return e1.first < e2. first;
        });
        auto w4 = v;
        std::stable_sort(w4.rbegin(), w4.rend(), [](Element const& e1, Element const& e2) {
           return e1.first > e2.first;
        });
        std::cout << std::boolalpha << std::equal(w3.begin(), w3.end(), w4.begin()) << "\n";
    
    }
    

    Output on LiveWorkSpace