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.
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
Reverse iterators simple iterate in the reverse direction of normal iterators.
So, both snippets will sort everything inside the range [first, last] both in ascending order. The difference is in the first it will use the < operator for comparison and in the second your given function.
In detail the first actually is sorting in non-ascending order but since you also reverse tho comparison it gets reversed again, which neutralizes the effect.
NOTE: Elements that would compare equal to each other are not guaranteed to keep their original relative order.
USEFUL REFERENCES: std::sort
, std::vector::begin
, std::vector::end
,
std::vector::rbegin
,
std::vector::rend
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