Как решить ошибку времени выполнения при нахождении наибольшего числа среди n чисел

#c

#c

Вопрос:

Поскольку я новичок в c , я получаю ошибку во время выполнения для первого примера (я имею в виду, что я тестировал свою программу с 5 примерами, на самом деле это происходит автоматически с помощью сайта для тестирования) моей программы, я знаю, что это из-за превышения времени ее запуска, но я не знаю, как это исправить. Моя программа получает n чисел от пользователя, находит наибольшее и печатает его.

 #include<iostream>
#include<curses.h>
using namespace std;
int main()
{
    int n;
    cin >> n;
    int *p = new int(n);

    for(int i = 1; i<=n; i  ){
        cin >> *(p i);
    }

    int largest = *p;

     for(int i = 1; i<=n; i  ){
         if(largest < *(p i))
             largest = *(p i);
      } 

     cout << largest;
     return(0);
 }  
 

Комментарии:

1. int *p=new int(n); — Это не делает того, что вы думаете. Посмотрите на это более внимательно.

2. Если вы не хотите найти указатель и ссылку на адрес памяти и т. Д. исправьте строки «int * p»

Ответ №1:

int *p=new int(n);

В строке выше выделяется только один int и устанавливается значение n . Он не выделяет массив n целых чисел.

Эта строка должна быть:

int *p=new int[n];

А затем delete [] p; освободить память.


Но еще лучше:

 #include <vector>
//...
std::vector<int> p(n);
 

это предпочтительный способ использования динамических массивов в C .

Тогда цикл ввода будет просто:

 for(int i=0;i<n; i  )
{
    cin >> p[i];
}
 

Тот же цикл ввода можно было бы использовать, если бы вы использовали версию указателя.


Тогда у вас есть эта ошибка:

for(int i=1;i<=n;i )

Массивы (и векторы) индексируются 0 , начиная с верхнего индекса at n-1 , где n — общее количество элементов. Этот цикл имеет ошибку «один за другим», когда он превышает верхний индекс в последнем цикле.

В принципе, любой цикл, который используется <= в качестве ограничивающего условия, является подозрительным. Эта строка должна быть:

for(int i=0; i<n; i )

(Обратите внимание, что я изменил приведенный выше код, чтобы исправить эту ошибку).


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

 #include <algorithm>
//...
int largest = *std::max_element(p, p   n);
 

и если использовать std::vector :

 #include <algorithm>
//...
int largest = *std::max_element(p.begin(), p.begin()   n);
 

Ответ №2:

Я прокомментировал предлагаемые изменения в этой слегка измененной версии:

 #include <iostream>

int main()
{
    unsigned n;             // don't allow a negative amount of numbers
    if(std::cin >> n) {     // check that "cin >> n" succeeds
        int* p=new int[n];  // allocate an array of n ints instead of one int with value n

        for(int i=0; i < n;   i) {               // corrected bounds [0,n) 
            if(not (std::cin >> p[i])) return 1; // check that "cin >> ..." succeeds
        }

        int largest = p[0];

        for(int i=1; i < n;   i) { // corrected bounds again, [1,n)
            if(largest < p[i])
                largest = p[i];
        }

        delete[] p; // free the memory when done

        std::cout << largest << 'n';
    }
}
 

Обратите внимание, что использование *(p i) выполняет то же самое, что и использование p[i] . Последнее часто предпочтительнее.

Это сработало бы, если бы все cin >> ... работало, но показывает некоторые опасности при использовании необработанных указателей. Если извлечение n целых чисел завершается неудачно, программа будет return 1 и пропускать выделенную память new int[n] .

Перезапись с использованием интеллектуального указателя ( std::unique_ptr<int[]> ), который автоматически освобождает память, когда она выходит за пределы области видимости:

 #include <iostream>
#include <memory>    // std::unique_ptr

int main()
{
    unsigned n;
    if(std::cin >> n) {
        std::unique_ptr<int[]> p(new int[n]);

        for(int i=0; i < n;   i) { // corrected bounds [0,n) 
            if(not (std::cin >> p[i])) return 1;             // will not leak "p"
        }

        int largest = p[0];

        for(int i=1; i < n;   i) {
            if(largest < p[i])
                largest = p[i];
        }

        std::cout << largest << 'n';
    } // p is automatically delete[]ed here
}
 

Однако часто бывает удобно хранить массив и его размер вместе, и для этого вы могли бы использовать std::vector<int> вместо. Он поставляется с множеством удобных функций-членов, таких как, size() — а также begin() и end() , что позволяет использовать его в циклах for на основе диапазона.

 #include <iostream>
#include <vector>    // std::vector

int main()
{
    unsigned n;
    if(std::cin >> n) {
        std::vector<int> p(n); // a vector of n ints

        // a range-based for loop, "elem" becomes a refrence to each element in "p":
        for(intamp; elem : p) {
            if(not (std::cin >> elem)) return 1;
        }

        int largest = p[0];

        for(int i = 1; i < p.size();   i) { // using the size() member function
            if(largest < p[i])
                largest = p[i];
        }

        std::cout << largest << 'n';
    }
}
 

Тем не менее, вам не нужно хранить какое-либо число в массиве, чтобы выяснить, какое наибольшее число. Вместо этого просто сравните входные данные с наибольшим числом в данный момент.

 #include <iostream>
#include <limits>   // std::numeric_limits

int main()
{
    unsigned n;

    if(std::cin >> n) {
        // initialize with the smallest possible int:
        int largest = std::numeric_limits<int>::min();

        while(n--) {
            int tmp;
            if(not (std::cin >> tmp)) return 1;

            if(largest < tmp)
                largest = tmp;
        }
        std::cout << largest << 'n';
    }
}