I wish to compute the median value from an array of floats in C++:
float Median( FloatArray const * constFloatArray )
{
FloatArray scratch = FloatArray( *constFloatArray );
int64_t const size = scratch.GetWidth() * scratch.GetHeight();
int64_t const mid = size / 2;
std::nth_element( scratch.begin(), scratch.begin() + mid, scratch.end() );
return scratch[ mid ];
}
The FloatArray contains a regular C++ array of floats.
I'm using std::nth_element
but wonder if there is a facility like nth_element
that works with const
data? Right now, I'm making a copy and then doing nth_element
before throwing the copy away. If there isn't something like nth_element
for const
data, is there a more efficient approach that uses the copy step to compute information and thus avoid a potentially additional O(n) loop? Perhaps the performance impact would be negligible? My array size could be on the order of 2 billion.
I'm not sure if it will be more efficient but you can save half of the copying by using std::partial_sort_copy
. We can use std::partial_sort_copy
to copy only half of the data into a new array and it will sort it into that array as it does so. Then all you need to do is get the last element for an odd number of elements, or average of last two for even amount of elements. Using a vector that would look like
int main()
{
std::vector<int> v{5, 6, 4, 3, 2, 6, 7, 9, 3, 10};
std::vector<int> r(v.size() / 2 + 1);
std::partial_sort_copy(v.begin(), v.end(), r.begin(), r.end());
if (r.size() % 2)
std::cout << r.back();
else
std::cout << (r[r.size() - 1] + r[r.size() - 2]) / 2.0;
}