Сделайте копию myVector
, рассортируйте ее и затем вычислите медиану этого значения.
Мы можем сделать немного лучше, чем просто используя std::sort
.Нам не нужно сортировать вектор полностью, чтобы найти медиану.Мы можем использовать std::nth_element
, чтобы найти средний элемент.Поскольку медиана вектора с четным числом элементов является средним из двух средних, нам нужно проделать еще немного работы, чтобы найти другой средний элемент в этом случае.std::nth_element
гарантирует, что все элементы, предшествующие середине, меньше, чем середина.Это не гарантирует их порядок за пределами этого, поэтому нам нужно использовать std::max_element
, чтобы найти самый большой элемент, предшествующий среднему элементу.
Еще одна вещь, которую вы, возможно, не рассмотрели, это случайгде myVector
пусто.Поиск медианы пустого вектора не имеет никакого смысла.В этом примере я просто использовал assert
, но вы можете вызвать исключение или что-то в этом роде.
double Median::calculate() const {
assert(!myVector.empty());
std::vector<double> myVectorCopy = myVector;
const auto middleItr = myVectorCopy.begin() + myVectorCopy.size() / 2;
std::nth_element(myVectorCopy.begin(), middleItr, myVectorCopy.end());
if (myVectorCopy.size() % 2 == 0) {
const auto leftMiddleItr = std::max_element(myVectorCopy.begin(), middleItr);
return (*leftMiddleItr + *middleItr) / 2.0;
} else {
return *middleItr;
}
}
Другой вариант - использовать другой контейнер, чтобы гарантировать, что элементы всегда сортируются.Вы можете рассмотреть возможность использования std::set
.Когда вы вставляете в std::set
, набор остается отсортированным, поэтому не нужно использовать std::sort
, std::nth_element
или std::max_element
, чтобы найти медиану.Вы бы получили средний элемент.