Вычислить медиану значений, сохраненных в векторе - C++?

Я - студент программирования, и для проекта я продолжаю работать, на вещей, которые я должен сделать, вычисляют среднее значение вектора международных значений. Я должен сделать это использование только функция вида от STL и векторных функций членства такой как .begin(), .end(), и .size().

Я, как также предполагается, удостоверяюсь, что нахожу медиану, имеет ли вектор нечетное число значений или четное число значений.

И я застреваю, ниже я включал свою попытку. Таким образом, где я иду не так, как надо? Я ценил бы, если Вы будете готовы дать мне некоторые подсказки или ресурсы для начинаний в правильном направлении.

Код:

int CalcMHWScore(const vector<int>& hWScores)
{
     const int DIVISOR = 2;
     double median;
     sort(hWScores.begin(), hWScores.end());
     if ((hWScores.size() % DIVISOR) == 0)
     {
         median = ((hWScores.begin() + hWScores.size()) + (hWScores.begin() + (hWScores.size() + 1))) / DIVISOR);
     }
     else 
     {
       median = ((hWScores.begin() + hWScores.size()) / DIVISOR)
     }

    return median;
}

Спасибо!!

34
задан Bill the Lizard 6 December 2012 в 18:10
поделиться

5 ответов

Вы выполняете дополнительное разделение и в целом, что делает его немного сложнее, чем должно быть Отказ Кроме того, нет необходимости создавать делитель, когда 2 на самом деле является более значимым в контексте.

double CalcMHWScore(vector<int> scores)
{
  size_t size = scores.size();

  if (size == 0)
  {
    return 0;  // Undefined, really.
  }
  else
  {
    sort(scores.begin(), scores.end());
    if (size % 2 == 0)
    {
      return (scores[size / 2 - 1] + scores[size / 2]) / 2;
    }
    else 
    {
      return scores[size / 2];
    }
  }
}
30
ответ дан 27 November 2019 в 16:04
поделиться

Нет необходимости полностью сортировать вектор: std :: nth_Element может сделать достаточно работы, чтобы поставить медиану в правильном положении. Увидеть мой ответ на этот вопрос для примера.

Конечно, это не помогает, если ваш учитель запрещает использовать правильный инструмент для работы.

59
ответ дан 27 November 2019 в 16:04
поделиться

Я даю ниже примерной программы, которая несколько похожа на реакцию MAX S.. Чтобы помочь первому продвинуту его знания и понимание, я сделал ряд изменений. У меня есть:

a) Изменена ссылка на CONT COND для вызова по значению, так как сорт захочет изменить порядок элементов в вашем векторе, (редактировать: я только что увидел, что Роб Кеннеди также сказал это, пока я Подготовка моего поста)

b) заменено Size_t с более подходящим вектором > :: size_type (на самом деле, удобный синоним последнего),

c) сохраненный размер / 2 к Промежуточная переменная,

d) выбросила исключение, если вектор пуст, и

E) я также представил условный оператор (? :).

На самом деле все эти исправления прямо из главы 4 «Ускоренного C ++» Koenig и Moo.

double median(vector<int> vec)
{
        typedef vector<int>::size_type vec_sz;

        vec_sz size = vec.size();
        if (size == 0)
                throw domain_error("median of an empty vector");

        sort(vec.begin(), vec.end());

        vec_sz mid = size/2;

        return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
4
ответ дан 27 November 2019 в 16:04
поделиться
const int DIVISOR = 2;

Не делайте этого. Это просто делает ваш код более запутанным. Вы, вероятно, читали руководящие принципы, не использующие волшебные числа, но ровность против нечто число номеров является фундаментальной собственностью, поэтому абстрагирующее это не дает никакой выгоды, а не затруднит читаемость.

if ((hWScores.size() % DIVISOR) == 0)
{
    median = ((hWScores.begin() + hWScores.size()) + (hWScores.begin() + (hWScores.size() + 1))) / DIVISOR);

Вы принимаете итератор до конца вектора, принимая еще один итератор, который указывает на конец вектора, добавляя итераторы вместе (что не является операцией, которая имеет смысл), а затем разделяет полученное значение итератор (который также не имеет смысла). Это более сложный случай; Я объясню, что делать для вектора нечетного размера сначала и оставьте чехол с четным размером как упражнение для вас.

}
else 
{
    median = ((hWScores.begin() + hWScores.size()) / DIVISOR)

Опять же, вы разделяете итератор. Что вы вместо этого хотите сделать, это увеличить итератор в начало Vector by HWSCORES.Size () / 2 Элементы:

    median = *(hWScores.begin() + hWScores.size() / 2);

и обратите внимание, что вам нужно итераторы получить значения из них. Было бы более простым, если вы использовали индексы:

    median = hWScores[hWScores.size() / 2];
4
ответ дан 27 November 2019 в 16:04
поделиться

Я не совсем уверен, что ваши ограничения на пользователь функций элементов вектора являются, но доступ к индексу с [] или AT () будут получать доступ к элементам Проще:

median = hWScores.at(hWScores.size() / 2);

Вы также можете работать с итераторами, как Начать () + Offset Как вы в настоящее время делаете, но тогда вам нужно сначала рассчитать правильное смещение со размером () / 2 и добавьте это в начать () , не наоборот. Также вам нужно разымевать результирующий итератор для доступа к фактическому значению в тот момент:

median = *(hWScores.begin() + hWScores.size()/2)
0
ответ дан 27 November 2019 в 16:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: