c++algorithmvectornth-element

Towards understanding nth_element


I am having a difficult time grasping how I should use std::nth_element, since I am little rusty.

The ref says:

Rearranges the elements in the range [first,last), in such a way that the element at the nth position is the element that would be in that position in a sorted sequence.

I want to take the n-th element of a subset of a vector, so I thought doing something like this:

std::nth_element (v.begin()+start-0, v.begin()+nTh-1, v.begin()+end);

would mean to take the subset of the vector v, from the start, until the end (exclusive), and then imagining that this subset is sorted, position the nTh element.

It seems that my understanding is off, since this toy example:

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

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; i++) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9

  std::random_shuffle (myvector.begin(), myvector.end());


  std::nth_element (myvector.begin() + 1 - 0, myvector.begin()+5-1, myvector.begin() + 5);
  std::cout <<  *(myvector.begin()+5-1) << std::endl;

  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

prints 9 as the requested element, while I would be expecting 5. What am I missing please?


Solution

  • Try:

    std::nth_element (myvector.begin(), myvector.begin()+ 4, myvector.end());
    

    instead of :

    std::nth_element (myvector.begin() + 1, 
                      myvector.begin() + 4, 
                      myvector.begin() + 5);
    

    You are shuffling and then calling nth_element for only a subsequence. This way you cannot what the returned element should be. If you do it for the whole sequence, then the answer is 5.