2015-12-28 4 views
3

Я новичок здесь и изучаю язык C++. Прямо сейчас я должен найти второй по величине элемент в массиве, но мой код иногда не дает мне корректного вывода. У меня есть следующий код, чтобы найти второй максимальный элемент.C++: поиск второго максимального элемента в массиве

for(int i = 0;i<size;i++) 
{ 
    if(arr[i] > max) 
    { 
     second_max = max; 
     max = arr[i]; 
    } 
} 

Этот код иногда работает, и иногда он не дает правильного значения второго максимального элемента. Пожалуйста, помогите мне, что я делаю неправильно?

+1

Пожалуйста, ** ** ваш вопрос с [mcve] или [SSCCE (короткий, самосохраненный, правильный пример)] (http://sscce.org) – NathanOliver

+0

Код немного неясен, что вы устанавливаете переменную «max» в первую очередь? –

+2

Мы не знаем, как вы инициализируете 'max' или' second_max'. Это (вероятно) проблема. – erip

ответ

8

Предполагая, что вы найти maximum и second_maximum элементы, что я заметил, что вы пропускаете сценарий, когда arr[i] больше second_max, но меньше, чем max например, для следующего сценария ваш код не будет работать нормально

max: 15 

second_max = 7 

arr[i] = 12 

добавить следующее условие для кода ниже первого if условия:

else if(arr[i] > second_max) 
{ 
    second_max = arr[i]; 
} 
+0

Хотя это будет работать, я думаю, что решение с сортировкой гораздо более надежное. Очевидно, что * правильно (и расширение до «третьего по величине» и т. Д. Очень очевидно). Конечно, сортировка будет медленнее для больших входов. –

+0

это должно быть 'else if', так как если это'> max', это будет '> second max', и вы установите оба параметра' arr [i] ', если не существует' else'. Также @MartinBonner, сортировка является излишним, линейное решение также может быть доказано правильно. –

+0

если 'arr [i] = 20', то' arr [i]> max' so 'second_max = 15; max = 20', тогда 'arr [i]> second max', поэтому' second_max' также будет установлен в 20. 'else' предотвращает это. –

5

Вот решение, используя только стандартные алгоритмы:

#include <iostream> 
#include <vector> 
#include <cassert> 

int second_max(std::vector<int> v) 
{ 
    using namespace std; 

    sort(begin(v), 
     end(v), 
     std::greater<>()); 

    auto last = unique(begin(v), 
         end(v)); 

    auto size = last - begin(v); 

    return (size == 0) 
    ? 0 
    : (size == 1) 
    ? v[0] 
    : v[1]; 
} 


int main() 
{ 
    using namespace std; 

    cout << second_max({ 3,5,7,7,2,4,3,2,6 }) << endl; 
    return 0; 
} 
+3

Вы также можете использовать ['std :: nth_element'] (http://en.cppreference.com/w/cpp/algorithm/nth_element) – NathanOliver

+0

@NathanOliver да, это более приятно - обновлено –

+0

@Richard Но' std :: unique' требует отсортированного диапазона. – LogicStuff

0

Вы можете использовать эту небольшую программу. Я использую только стандартные алгоритмы std, и это самое простое, о котором я могу думать.

#include <array> 
#include <algorithm> 
#include <iostream> 

int main() 
{ 
    std::array<int, 10> ar = {1, 5, 15, 2, 3, 5, 6, 8, 9, 14}; 

    // Sort the array 
    std::sort(std::begin(ar), std::end(ar)); 

    // Print the second max element 
    std::cout << ar[ar.size() - 2]; 
} 
+0

Недостаточно общего: что произойдет, если arr.size() меньше 2? –

+0

Ну, если arr.size() меньше 2, вам не нужно std, чтобы найти второй максимум! написал этот пример, имея в виду, что у него будет статический массив элементов, а не вектор. – TheCrafter

0

Логика вашего оператора if не заполнена. Вот рабочая версия:

for(int i = 0; i<size; i++) 
    { 
    if(max < arr[i]) { 
     second_max = max; 
     max = arr[i]; 
    } 
    else if(second_max < arr[i]) 
     second_max = arr[i]; 
    } 
2

Вместо std::sort это должно быть сделано с std::nth_element. Это именно тот сценарий, для которого он был разработан, и избегает сортировки всей коллекции, когда вы заботитесь только о нескольких элементах.

+0

Еще лучше, он выполняет частичную сортировку для вас, поэтому 'std :: nth_element' может сочетаться с' std :: sort', чтобы действовать как 'nlargest' (аналогично [heapq.nlargest' Python] (https://docs.python.org/3/library/heapq.html#heapq.nlargest)); вы можете получить X наибольший (для любого X в порядке) с работой, которая линейна по длине ввода и только «O (n log n)» в количестве необходимых максимальных элементов: 'std :: nth_element (std :: begin (vals), std :: begin (vals) + (nummax - 1), std :: end (vals), std :: больше <>()); за которым следует 'std :: sort' только первые элементы nummax. Это лучший ответ для производственного кода. – ShadowRanger

+0

@ShadowRanger: Если это то, что вы хотите, вы можете просто использовать ['std :: partial_sort'] (http://en.cppreference.com/w/cpp/algorithm/partial_sort). Не нужно вручную комбинировать 'std :: nth_element' с' std :: sort' – MikeMB

+0

@MikeMB: вы можете использовать partial_sort, но использовать его для поиска самых больших элементов тоже не тривиально - это не сразу очевидно (по крайней мере мне), что это огромное улучшение. В любом случае мы получаем довольно много путей от первоначального вопроса. В любом случае мы получаем довольно далеко от исходного вопроса. –

Смежные вопросы