2

I'm trying to sort a vector of unsigned int in lexicographical order.

The std::lexicographical_compare function only supports iterators so I'm not sure how to compare two numbers.

This is the code I'm trying to use:

std::sort(myVector->begin(),myVector->end(), [](const unsigned int& x, const unsigned int& y){
        std::vector<unsigned int> tmp1(x);
        std::vector<unsigned int> tmp2(y);
        return lexicographical_compare(tmp1.begin(),tmp1.end(),tmp2.begin(),tmp2.end());
} );
SuperMurloc
  • 189
  • 1
  • 3
  • 13
  • So you want to compare numbers by their decimal digits? – wilx Oct 25 '16 at 06:08
  • 3
    Can you give an example of when a number is lexicographically less but numerically greater than or equal to another? – kfsone Oct 25 '16 at 06:12
  • are you sure that your code is work? – Ebrahimi Oct 25 '16 at 06:16
  • 1
    I'm also interested in why you would want to do this. Also, you could fake a single element iterator range with &number and &number+1. – rubenvb Oct 25 '16 at 06:20
  • I am superb confused. – P0W Oct 25 '16 at 06:29
  • As rubenvb said [you may use 1-element range of iterators](http://stackoverflow.com/questions/37033682/), but if number `a` is less then number `b` (even converted to string) then `a` is lexicographically less then `b`. Your question in main part does not make sense at all. – Tomilov Anatoliy Oct 27 '16 at 02:30

2 Answers2

3

C++11 introduces std::to_string

You can use from to_string as below:

std::sort(myVector->begin(),myVector->end(), [](const unsigned int& x, const unsigned int& y){
        std::string tmp1 = std::to_string(x);
        std::string tmp2 = std::to_string(y);
        return lexicographical_compare(tmp1.begin(),tmp1.end(),tmp2.begin(),tmp2.end());
} );
Ebrahimi
  • 1,209
  • 8
  • 15
-1

I assume you have some good reasons, but allow me to ask: Why are you sorting two int's by using the std::lexicographical order? In which scenario is 0 not less than 1, for example?

I suggest for comparing the scalars you want to use std::less . Same as std lib itself does.

Your code (from the question) might contain a lambda that will use std::less and that will work perfectly. But let us go one step further and deliver some reusable code ready for pasting into your code. Here is one example:

 /// sort a range in place
 template< typename T>
 inline void dbj_sort( T & range_ ) 
{
// the type of elements range contains
using ET = typename T::value_type;
// use of the std::less type
using LT = std::less<ET>;
// make its instance whose 'operator ()'
// we will use
LT less{};

std::sort(
    range_.begin(),
    range_.end(),
    [&]( const ET & a, const ET & b) {
        return less(a, b);
    });
}

The above is using std::less<> internally. And it will sort anything that has begin() and end() and public type of the elements it contains. In other words implementation of the range concept.

Example usage:

std::vector<int> iv_ = { 13, 42, 2 };
dbj_sort(iv_);

std::array<int,3> ia_ = { 13, 42, 2 };
dbj_sort(ia_);

std:: generics in action ...

Why is std::less working here? Among other obvious things, because it compares two scalars. std::lexicographical_compare compares two ordinals.

std::lexicographical_compare might be used two compare two vectors, not two elements from one vector containing scalars.

HTH