0

This program is supposed to find the second largest integer. I have taken it from a book.

When I enter to find the second largest number among 4 5 1 2 3, it doesn't pick 4 as the second largest. I think on line 16 the code should be arr[0] and not arr[1]. Am I correct or am I missing something?

#include <stdio.h>
int main()
{
    int i, n, arr[20], large, second_large;
    printf("\n Enter the number of elements in the array : ");
    scanf("%d", &n);
    printf("\n Enter the elements");
    for(i=0;i<n;i++)
        scanf("%d",&arr[i]);
    large = arr[0];
    for(i=1;i<n;i++)
    {
        if(arr[i]>large)
            large = arr[i];
    }
    second_large = arr[1]; // line 16
    for(i=0;i<n;i++)
    {
        if(arr[i] != large)
        {
            if(arr[i]>second_large)
                second_large = arr[i];
        }
    }
    printf("\n The numbers you entered are : ");
    for(i=0;i<n;i++)
        printf("\t %d", arr[i]);
    printf("\n The largest of these numbers is : %d",large);
    printf("\n The second largest of these numbers is : %d",second_large);
    return 0;
}
nab saw
  • 15
  • 3
  • 3
    did you take it from a book about C ? If you want to learn C++ you better use a book about C++ https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – 463035818_is_not_an_ai Jan 10 '22 at 16:53
  • 1
    Neither would be correct. – Jarod42 Jan 10 '22 at 16:57
  • If you have the values `1, 2, 3, 4, 4` is `4` supposed to be the second largest, or `3`? – ChrisMM Jan 10 '22 at 16:58
  • 1
    Usually you can solve a problem like this without an array. You test the numbers as they come in and keep the largest and second largest seen so far. When input ends, return the second largest. – user4581301 Jan 10 '22 at 17:02
  • If you're using C, see `qsort`. If you're trying to learn C++, I agree with the advice to get a C++ book. – MSalters Jan 10 '22 at 17:03

3 Answers3

2

Your code reads like "C", this is C++20 code for the same problem : (for manual input, use std::cin and values.push_back)

#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
    constexpr std::size_t second_largest_index = 1ul;

    std::vector<int> values{ 0,2,8,7,5,4,1,3,9,6 };
    std::ranges::nth_element(values, values.begin() + 1, std::ranges::greater());
    std::cout << "the second largest value = " << values[second_largest_index];
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • 5
    [`std::nth_element`](https://en.cppreference.com/w/cpp/algorithm/nth_element)/[`std::partial_sort`](https://en.cppreference.com/w/cpp/algorithm/partial_sort) have better complexity that a full sort. – Jarod42 Jan 10 '22 at 17:13
  • `second_largest` -> `second_largest_index` seems a better name. – Jarod42 Jan 10 '22 at 17:14
  • 3
    `std::nth_element` is designed specifically for this type of problem, and has linear complexity. – Drew Dormann Jan 10 '22 at 17:24
  • 1
    Thanks guys, keep forgetting about those functions. And I agree with the naming of the variable. Example updated. – Pepijn Kramer Jan 10 '22 at 17:57
0

There are some minor errors in the code itself that can cause the problem. Once, As you know that the array starts at index 0 but in the for loop you did count it from 1. so instead of:

for(i=1;i<n;i++)
{
    if(arr[i]>large)
        large = arr[i];
}

You should start your for loop also from zero, otherwise, you are not counting one.

Also for more simplicity, you can write your code like this:

#include <iostream>
using namespace std;
int main(){
   int n, num[50], biggest, secondBiggest;
   cout<<"Enter number of elements in your array: ";
   cin>>n;
   for(int i=0; i<n; i++){
      cout<<"Enter your "<<(i+1)<<" Number: ";
      cin>>num[i];
   }
   
   if(num[0]<num[1]){ 
      biggest= num[1];
      secondBiggest= num[0];
   }
   else{ 
      biggest= num[0];
      secondBiggest= num[1];
   }
   for (int i = 2; i< n ; i ++) {
      
      if (num[i] > biggest) {
         secondBiggest= biggest;
         biggest= num[i];
      }
      
      else if (num[i] > secondBiggest && num[i] != biggest) {
         secondBiggest= num[i];
      }
   }
   cout<<"Second Largest Element in array is: "<<secondBiggest;
   return 0;
}
Shayan Faghani
  • 243
  • 1
  • 9
  • Be careful with generalities. The loop at the top of this answer that looks for `large` is correct, starting at index 1. The code has already looked at `arr[0]` and copied it into `large`, so it only needs to look at the rest of the values. – Pete Becker Jan 10 '22 at 17:13
0

This statement

second_large = arr[1]; 

at once selects the largest number in the array { 4, 5, 1, 2, 3 }.

So the expression of the nested if statement within this for loop

for(i=0;i<n;i++)
{
    if(arr[i] != large)
    {
        if(arr[i]>second_large)
            second_large = arr[i];
    }
}

never evaluates to true. That is the second largest number will always equal to the first largest number.

Pay attention to that in general an array can contain all elements equal each other.

I can suggest the following approach.

large = 0;
second_large = n;

i = 1;
while ( i < n && arr[i] == arr[large] ) ++i; 

if ( i < n )
{
    if ( arr[large] < arr[i] )
    {
        large = i;
        second_large = 0;
    }
    else
    {
        second_large = i;
    }

    while ( ++i < n )
    {
        if ( arr[large] < arr[i] )
        {
            second_large = large;
            large = i;
        }
        else if ( arr[second_large] < arr[i] )
        {
            second_large = i;
        }
    }
}

if ( second_large == n )
{
    puts( "\nAll elements are equal each other." );
}
else
{
    printf("\nThe largest of these numbers is : %d", arr[large] );
    printf("\nThe second largest of these numbers is : %d", arr[second_large] );
}

Here is a demonstration C program (It is a C program because the program provided by you in fact has nothing from C++)

#include <stdio.h>

int main( void )
{
    int arr[] = { 4, 5, 1, 2, 3 };
    const size_t n = sizeof( arr ) / sizeof( *arr );

    size_t large = 0;
    size_t second_large = n;

    size_t i = 1;
    while (i < n && arr[i] == arr[large]) ++i;

    if (i < n)
    {
        if (arr[large] < arr[i])
        {
            large = i;
            second_large = 0;
        }
        else
        {
            second_large = i;
        }

        while (++i < n)
        {
            if (arr[large] < arr[i])
            {
                second_large = large;
                large = i;
            }
            else if (arr[second_large] < arr[i])
            {
                second_large = i;
            }
        }
    }

    for (i = 0; i < n; i++)
    {
        printf( "%d ", arr[i] );
    }
    putchar( '\n' );

    if (second_large == n)
    {
        puts( "All elements are equal each other." );
    }
    else
    {
        printf( "The largest of these numbers is : %d\n", arr[large] );
        printf( "The second largest of these numbers is : %d\n", arr[second_large] );
    }
}

The program output is

4 5 1 2 3
The largest of these numbers is : 5
The second largest of these numbers is : 4

A C++ demonstration program can look the following way

#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>

int main()
{
    int arr[] = { 4, 5, 1, 2, 3 };
    const size_t n = sizeof( arr ) / sizeof( *arr );

    auto last = std::next( arr, n );

    for (auto first = std::begin( arr ); first != last; ++first)
    {
        std::cout << *first << ' ';
    }
    std::cout << '\n';

    auto it = std::adjacent_find( std::begin( arr ), last,
                                  std::not_equal_to<>() );

    if (it == last)
    {
        std::cout << "All elements are equal each other.\n";
    }
    else
    {
        auto [second_large, large] = std::minmax( { it, std::next( it ) },
            []( const auto &it1, const auto &it2 )
            {
                return *it1 < *it2;
            } );

        for (auto current = std::next( it, 2 ); current != last; ++current)
        {
            if (*large < *current)
            {
                second_large = std::exchange( large, current );
            }
            else if (*second_large < *current)
            {
                second_large = current;
            }
        }

        std::cout << "The largest of these numbers is "
                  << *large << " that is present at position "
                  << std::distance( std::begin( arr ), large )
                  << '\n';
        std::cout << "The second largest of these numbers is "
                  << *second_large << " that is present at position "
                  << std::distance( std::begin( arr ), second_large )
                  << '\n';
    }
}

The program output is

4 5 1 2 3
The largest of these numbers is 5 that is present at position 1
The second largest of these numbers is 4 that is present at position 0
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335