Поиск наивысшего балла в одном массиве и сопоставление этого индекса с индексом другого массива

мне было интересно, может ли кто-то посмотреть мою программу. Мне нужна помощь, чтобы выяснить, как заполнить динамический массив, размер которого является счетчиком, который увеличивается, когда условие удовлетворено, и как найти самый высокий двойник в этом массиве. Спасибо всем!

Вот в чем проблема:
Напишите программу, которая принимает N баллов и находит баллы каждого участника
1. Введите N (для количества судей, которые будут давать оценку)
2. Введите идентификатор участника
3. Найти среднее значение из этих оценок (найти max и min, вычесть их из общего, чтобы разделить на N-2)
Программа должна делать это до тех пор, пока введенный идентификатор участника не будет недействительным (отрицательные номера).
Это то, что у меня есть до сих пор.




#include<iostream>
using namespace std;
double average(int N, int scores[])
int main()
{
    int N, id, contestants = 0, return_scores = 0;
    int scores[10];
    int *contestant = new  int[contestants];
    double *avg_scores = new  double[contestants];
    double avg;
    int highest, index;

    cout << "Number of Judges: " << endl;
    cin >> N;
    cout << "Enter ID: " << endl;
    cin >> id;
    if (id >= 0)
    {
        contestants++;
    }
    while (id >=0)
    {
        //populate the contestants array with id if id is valid
        for (int i = 0;i < contestants;i++)
        {
            contestant[i] = id;
        }


        cout << "Enter scores:" << endl;
        for (int i = 0;i < N;i++)
        {
            cin >> scores[i];
        }

        //call function to calculate average
        avg = average(N, scores);
        for (int i = 0;i < contestants;i++)
        {
            avg_scores[i] = avg;
        }

        highest = int(avg_scores[0]);

        cout << "Contestant: " << id << " " << avg << endl;
        cout << "n";
        cout << "Enter contestant ID: " << endl;
        cin >> id;
    }
    //find the index to the highest score and match it with the contestants array
    for (int i = 0;i < contestants;i++)
    {
        if (highest < avg_scores[i])
        {
            highest = int(avg_scores[i]);
            index = highest;
        }
    }
    cout << "Contestant: " << contestant[index] << " had the highest score.n";
    return 0;
}

double average(int N, int scores[10])
{
    double total = 0;
    double min = scores[0], max = scores[0];
    double average = 0.0;
    double drop = min + max;
    //find the total/min/max
    for (int i = 0;i < N;i++)
    {
        total += scores[i];
        if (scores[i] < min)
        {
            min = scores[i];
        }

        if (scores[i] > max)
        {
            max = scores[i];
        }
    }
    //average
    average = ((total - min - max) / (N-2));
    return average;
}

1 ответ

  1. Одна довольно серьезная проблема в вашем коде находится в начале:

    int N, id, contestants = 0, return_scores = 0;
    int scores[10];
    int *contestant = new  int[contestants];
    double *avg_scores = new  double[contestants];
    

    При выделении массивов приведенный выше код выделяет contestants
    целые числа для contestantмассива и contestantsдвойники для массива
    avg_scores. К сожалению, contestantsэто ноль, что означает, что вы
    не выделяя памяти вообще. Что еще хуже, вы никогда не перераспределяете
    любой из этих массивов, поэтому ваша программа имеет неопределенное поведение, потому что
    вы храните вещи в массивах нулевой длины.

    У вас также есть другие проблемы, такие как:

        for (int i = 0;i < contestants;i++)
        {
            contestant[i] = id;
        }
    

    …который всегда стирает каждый идентификатор участника, сохраненный ранее. Вы делаете то же самое со средними баллами.

    Кроме того, вы позволяете пользователю указать количество судей в Nпеременной, а затем считываете Nсчет в scoresмассив. Но по какой-то причине вы объявили scoresкак массив фиксированной длины, который всегда имеет 10 элементов. Это означает, что если я введу 11 в качестве числа судей, вы запишете конец массива. Следует динамически выделять scoresмассив так, чтобы он содержал Nэлементы.

    Для ваших идентификаторов участников и оценок, похоже, вам нужно сначала выделить некоторую память, а затем
    выделите дополнительную память по мере чтения дополнительных данных, так как вы
    не имеют никакого способа узнать заранее, сколько конкурсантов вы
    собираюсь почитать. Есть два выхода из этого:

    1. Спросите количество участников заранее, как вы делаете с
      судья. Это простой путь.
    2. Увеличение размера массива contestantandavg_scores
      как Вы читаете в больше данных.

    Я не знаю, какой из них требуется вашему профессору, поэтому я покажу
    вы Вариант 2, так как он позволяет сохранить основную структуру
    ваша программа. Я предполагаю, что использование std::vectorзапрещено.
    Это был бы действительно легкий путь.

    Для каждого массива потребуется три переменные:

    int *contestant;
    size_t contestant_capacity=0;
    size_t contestants=0;
    

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

    #include <cstring>
    
    int *add_contestant_id(int *array, size_t *capacity, size_t *size, int id)
    {
        if(*size == *capacity) {
                *capacity *= 2;
                int *new_array = new int[*capacity];
                memcpy(new_array, array, (*size)*sizeof(int));
                delete[] array;
                array = new_array;
        }
        array[(*size)++] = id;
        return array;
    }
    

    Установка его в отдельной функции сохраняет всю эту бухгалтерию
    вашей mainфункции, делая основной цикл более простым и поэтому
    легкий для понимания.

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

    template <typename T>
    int *add_value(T *array, size_t *capacity, size_t *size, T value)
    {
        if(*size == *capacity) {
                *capacity *= 2;
                T *new_array = new T[*capacity];
                memcpy(new_array, array, (*size)*sizeof(T));
                delete[] array;
                array = new_array;
        }
        array[(*size)++] = value;
        return array;
    }
    

    Привычка разбивать код на функции-это хорошо
    идея. Разбиение кода на мелкие кусочки облегчает
    голова вокруг проблемы. Когда вы читаете идентификатор участника, это должно быть
    своя собственная функция:

    int read_contestant_id()
    {
        int id;
        cout << "Enter ID: " << endl;
        cin >> id;
        return id;
    }
    

    Затем while(id >= 0)цикл можно переписать как:

    for(int id=read_contestant_id(); id >= 0; id=read_contestant_id()) {
        ...
    }
    

    Чтение среднего балла для одного игрока также является хорошим кандидатом на
    отдельная функция (и хорошее место для динамического выделения scoresмассива):

    double read_avg_score(int nJudges)
    {
        int *scores = new int[nJudges];
        for(int i=0; i<nJudges; i++) {
                cout << "Enter scores:" << endl;
                cin >> scores[i];
        }
    
        double return_val = average(nJudges, scores);
        delete[] scores;
        return return_val;
    }
    

    После перезаписи цикла чтения для использования этих функций код
    похоже на то, что у меня ниже. Обратите внимание, как вся mainфункция теперь помещается на экране сразу.

    Со всеми серьезными ошибками исправлены, единственная ошибка слева
    чтобы исправить это выяснить разницу между высоким баллом и
    его индекс в массиве, который должен быть проще сейчас, так как остальная часть программы На самом деле делает то, что вы думали, что он делал раньше:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    double average(int N, int *scores);
    double read_avg_score(int nJudges);
    int read_contestant_id();
    double *add_average(double *array, size_t *capacity, size_t *size, double avg);
    int *add_contestant_id(int *array, size_t *capacity, size_t *size, int id);
    
    int main()
    {
        int id;
        size_t N=0, contestants = 0, contestants_capacity=1; 
        size_t avg_scores_capacity = 1, avg_scores_size=0;
        int *contestant = new  int[contestants_capacity];
        double *avg_scores = new  double[avg_scores_capacity];
        double avg;
        int highest, index;
    
        while(N == 0) {
            cout << "Number of Judges: " << endl;
            cin >> N;
            if(N == 0) {
                 cout << "You can't have ZERO judges." << endl;
            }
        }
        for(int id=read_contestant_id(); id >= 0; id=read_contestant_id())
        {
            // populate the contestants array with id, which is ensured to be
            // valid by the for-loop invariant.
            contestant = add_contestant_id(contestant, &contestants_capacity, &contestants, id);
    
            // Read the scores, calculate the average, and populate the avg_scores array.
    
            avg_scores = add_average(avg_scores, &avg_scores_capacity, &avg_scores_size,
                                     read_avg_score(N));
        }
        //find the index to the highest score and match it with the contestants array
        for (int i = 0; i < contestants; i++)
        {
            if (highest < avg_scores[i])
            {
                highest = int(avg_scores[i]); // <-- Maybe highest should be a double.
                index = highest; // <-- Here's where you made the mistake.
            }
        }
        cout << "Contestant: " << contestant[index] << " had the highest score.\n";
        return 0;
    }
    
    double average(int N, int *scores)
    {
        double total = 0;
        double min = scores[0], max = scores[0];
        double average = 0.0;
        double drop = min + max;
        //find the total/min/max
        for (int i = 0;i < N;i++)
        {
            total += scores[i];
            if (scores[i] < min)
            {
                min = scores[i];
            }
    
            if (scores[i] > max)
            {
                max = scores[i];
            }
        }
        //average
        average = ((total - min - max) / (N-2));
        return average;
    }
    
    
    double read_avg_score(int nJudges)
    {
            int *scores = new int[nJudges];
            for(int i=0; i<nJudges; i++) {
                    cout << "Enter scores:" << endl;
                    cin >> scores[i];
            }
    
            double return_val = average(nJudges, scores);
            delete[] scores;
            return return_val;
    }
    
    int read_contestant_id()
    {
        int id;
        cout << "Enter ID: " << endl;
        cin >> id;
        return id;
    }
    
    
    int *add_contestant_id(int *array, size_t *capacity, size_t *size, int id)
    {
            if(*size == *capacity) {
                    *capacity *= 2;
                    int *new_array = new int[*capacity];
                    memcpy(new_array, array, (*size)*sizeof(int));
                    delete[] array;
                    array = new_array;
            }
            array[(*size)++] = id;
            return array;
    }
    
    double *add_average(double *array, size_t *capacity, size_t *size, double avg)
    {
            if(*size == *capacity) {
                    *capacity *= 2;
                    double *new_array = new double[*capacity];
                    memcpy(new_array, array, (*size)*sizeof(double));
                    delete[] array;
                    array = new_array;
            }
            array[(*size)++] = avg;
            return array;
    }