2

From a given unsorted vector I want to get the nth smallest element. I figured out that there is a method in the standard library. But I do not understand the following result.

I took the vector with entries {3,4,5,2,3} and want to have the 2th smallest element. If I execute the following code, I get the number 2 at the second position, actually it should be the 3. Because 2 is the 1st smallest element and not the second.

What is my mistake?

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

int main()
{
  std::vector<size_t> temp;
  temp.assign({3,4,5,2,3});
  std::nth_element (temp.begin(), temp.begin()+2, temp.end());
  std::cout << std::endl;
  for(size_t i=0;i<temp.size();i++){ printf("%.2f\n",(double)temp[i]);  }
}
DerJFK
  • 221
  • 2
  • 12
  • 1
    Note your `assign` call could just use the constructor: `std::vector temp{3,4,5,2,3};` – chris Jun 07 '15 at 17:58

2 Answers2

5

temp.begin()+2 gives you the third element of the vector, not the second. The first element is temp.begin() (i.e. temp.begin() + 0), and the second element is temp.begin() + 1. So you want to do this:

std::nth_element (temp.begin(), temp.begin()+1, temp.end());
Benjamin Lindley
  • 95,516
  • 8
  • 172
  • 256
2

If you want to get the second smallest element then you have to use iterator

temp.begin() + 1

or it can be written like

std::next( temp.begin() )

Here is a demonstrative program

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

int main()
{
    std::vector<size_t> v = { 3, 4, 5, 2, 3 };

    std::nth_element( v.begin(), std::next( v.begin() ), v.end() );

    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;
}

The program output is

2 3 4 3 5

As you see in the second position there is the second smallest element 3.

In my opinion it is not a good approach because it changes the order of elements in the vector. Usually you may not change the order of elements of the underlaying container.

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268