views:

336

answers:

3

Hello i Have a "vector of vectors" that looks something like this

3 1 2 0 77
0 3 1 2 44
1 0 3 2 29
3 0 1 2 49

I would like to sort them according to the last element in every row so that it would look like this in the end

1 0 3 2 29 
0 3 1 2 44
3 0 1 2 49
3 1 2 0 77

Of course my real example is a lot more complex... but this is basically what I need to get done. Right now I use this snippet which seems to sort according to the first elements.

vector<vector<int>>population;
partial_sort( population.begin(),population.begin()+10, population.end() );

Thanks for any help /Buxley

+5  A: 

Use a simple std::sort and pass a functor that compares only the vector's last elements.

Partial_sort rearranges the elements in the range [first, last) so that they are partially in ascending order. Specifically, it places the smallest middle - first elements, sorted in ascending order, into the range [first, middle). The remaining last - middle elements are placed, in an unspecified order, into the range [middle, last).

rpg
thanks..Well I want to partially sort in my example to save cpu time...But how do I "pass a functor" which should be done in the same way regardless of sort/partial_sort..
mrbuxley
See MadKeithV's answer for an example implementation.
rpg
+2  A: 

You can pass along a comparator as the fourth argument to std::partial_sort or std::sort, so just write a function object with a call operator taking two vector arguments that compare your vectors the way you want to.

Mikael Auno
+7  A: 

You can use std::sort with a functor object that has a strict weak ordering for vectors. I.e. you define a vector-less-than functor that orders two vectors correctly, something like this (off the top of my head). Edit: after comments, added checking for one or two empty vectors, which does make things trickier.

class CustomVectorCompare
  {
  public:
    bool operator<(const std::vector<int> &i_lhs, const std::vector<int> &i_rhs)
      {
      if(i_rhs.empty())
        return false; // If right side is empty, left can only be equal or larger

      if(i_lhs.empty())
        return true;  // Consider an empty vector to be "smaller" 
                       // than any non-empty vector.       

      return i_lhs.back() < i_rhs.back();
      }
  }

std::sort(population.begin(), population.end(), CustomVectorCompare());
MadKeithV
Thanks will try it out...Thought I could just put a parameter or something to get it to compare the nth elements but...
mrbuxley
Make sure you augment this code for the case where one of the vectors is emoty.
sbi
Good point, sbi.
MadKeithV
You can also use vector::back() instead of *vector::rbegin()
rpg
If both vectors are empty, they are in fact equal...
rpg
Dur... where's my head at this morning... Thanks for that RPG.
MadKeithV
And `vector<>::back()`, too, must not be called on empty vectors...
sbi
In the above reworking, that never happens. It early-outs for either vector being empty.
MadKeithV
A very good solution, IMO. Unfortunately, I've already up-voted it, so I can't up-vote again. `:)`
sbi