0

I have searched many websites for this question. They are doing it by some different approach. This code is just not giving output if I input first element of array as largest i.e. a[0]. I think some minor change is required. can anyone please tell me?

#include <stdio.h>

int main() {
    int a[10], n;
    int largest1, largest2, i;

    printf("enter number of elements you want in array");
    scanf("%d", &n);
    printf("enter elements");
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    largest1 = a[0];
    for (i = 0; i < n; i++) {
        if (a[i] > largest1) {
            largest1 = a[i];
        }
    }
    largest2 = a[0];
    for (i = 1; i < n; i++) {
        if (a[i] > largest2 && a[i] < largest1)
            largest2 = a[i];
    }
    printf("First and second largest number is %d and %d ", largest1, largest2);
}
3
  • Sort them and take the last two elements. If it's some sort of exercise, we just had a question like this one, it was getting the max and min of a 4 element array in 4 comparisons. Commented Feb 22, 2017 at 20:09
  • 2
    Sorting is not the best algorithm you could use there. Sorting has a complexity O(n * log(n)) (if done correctly), while you can find the maximum in a linear time. Commented Feb 22, 2017 at 20:13
  • I see a first issue here with the initialization of largest2. If a[0] is the largest, the condition in the second for loop will always be false, and largest1 and largest2 will both be a[0]. Commented Feb 22, 2017 at 20:15

14 Answers 14

10

(I'm going to ignore handling input, its just a distraction.)

The easy way is to sort it.

#include <stdlib.h>
#include <stdio.h>

int cmp_int( const void *a, const void *b ) {
    return *(int*)a - *(int*)b;
}

int main() {
    int a[] = { 1, 5, 3, 2, 0, 5, 7, 6 };
    const int n = sizeof(a) / sizeof(a[0]);

    qsort(a, n, sizeof(a[0]), cmp_int);
    printf("%d %d\n", a[n-1], a[n-2]);
}

But that isn't the most efficient because it's O(n log n), meaning as the array gets bigger the number of comparisons gets bigger faster. Not too fast, slower than exponential, but we can do better.

We can do it in O(n) or "linear time" meaning as the array gets bigger the number of comparisons grows at the same rate.

Loop through the array tracking the max, that's the usual way to find the max. When you find a new max, the old max becomes the 2nd highest number.

Instead of having a second loop to find the 2nd highest number, throw in a special case for running into the 2nd highest number.

#include <stdio.h>
#include <limits.h>

int main() {
    int a[] = { 1, 5, 3, 2, 0, 5, 7, 6 };
    // This trick to get the size of an array only works on stack allocated arrays.
    const int n = sizeof(a) / sizeof(a[0]);

    // Initialize them to the smallest possible integer.
    // This avoids having to special case the first elements.
    int max = INT_MIN;
    int second_max = INT_MIN;

    for( int i = 0; i < n; i++ ) {
        // Is it the max?
        if( a[i] > max ) {
            // Make the old max the new 2nd max.
            second_max = max;
            // This is the new max.
            max = a[i];
        }
        // It's not the max, is it the 2nd max?
        else if( a[i] > second_max ) {
            second_max = a[i];
        }
    }

    printf("max: %d, second_max: %d\n", max, second_max);
}

There might be a more elegant way to do it, but that will do, at most, 2n comparisons. At best it will do n.

Note that there's an open question of what to do with { 1, 2, 3, 3 }. Should that return 3, 3 or 2, 3? I'll leave that to you to decide and adjust accordingly.

Sign up to request clarification or add additional context in comments.

Comments

2

The problem with your code is a logic problem (which is what most coding is about). If the largest number is first then it gets the second largest number wrong ... why?

Well, look at your logic for deciding on the second largest number. You first set it to be equal to the first element in the array and then you go through the array and change the index if the element is greater than the current second largest number (which will never be true because we already set it to be the largest number!).

To solve it you can special case this: check if the largest number was the first and if so then set it to the second element (and then special case the issue of someone asking to find the highest two elements in a one element array, without reading past the end of an array.)

I think the method given in chqrlie's answer to do this all in one pass is best. And logical too: write a program to find the largest number. Second largest number, well that's just the one which was previously the largest!

Comments

0

You need to preserve the index of array members better as they are unique Here is a working code with few changes:

#include<stdio.h>
int main()
{
    int a[10],n;
    int largest1,largest2,i;

    printf("enter number of elements you want in array");
    scanf("%d",&n);
    printf("enter elements");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    largest1=0;
    for(i=0;i<n;i++)
    {
        if(a[i]>a[largest1])
        {
            largest1=i;
        }
    }
    if(largest1!=0) // this condition to select another index than the largest
        largest2=0;
    else
        largest2=n-1;
    for(i=0;i<n && i != largest1 ;i++)
    {
        if(a[i]>a[largest2])
            largest2=i;
    }
    printf("First and second largest number is %d and %d ",a[largest1],a[largest2]);
}

Note that when the array is of size 1 values will be the same.

Comments

0

The question is ambiguous: if the array may contain duplicate values, are you supposed to find the 2 largest distinct values or the two largest possibly identical values?

Your code seems to indicate you want the first approach, but you have a problem if the largest value is a[0]. You should use an extra boolean to keep track of whether you have found a different value yet.

You should also test the return value of the different scanf() calls and return 0 from main().

Here is a modified version:

#include <stdio.h>

int main(void) {
    int a[10], n, i;
    int largest1, largest2, has_largest2;

    printf("enter number of elements you want in array: ");
    if (scanf("%d", &n) != 1)
        return 1;
    if (n < 2) {
        printf("need at least 2 elements\n");
        return 1;
    }
    printf("enter elements: ");
    for (i = 0; i < n; i++) {
        if (scanf("%d", &a[i]) != 1) {
            printf("input error\n");
            return 1;
        }
    }
    largest1 = a[0];
    for (i = 1; i < n; i++) {
        if (a[i] > largest1) {
            largest1 = a[i];
        }
    }
    has_largest2 = largest2 = 0;
    for (i = 0; i < n; i++) {
        if (a[i] < largest1) {
            if (!has_largest2) {
                has_largest2 = 1;
                largest2 = a[i];
            } else
            if (a[i] > largest2) {
                largest2 = a[i];
            }
        }
    }
    if (has_largest2) {
        printf("First and second largest number is %d and %d\n",
               largest1, largest2);
    } else {
        printf("All values are identical to %d\n", largest1);
    }
    return 0;
}

Comments

0

You can do it best in one pass.

largest and largest2 are set to INT_MIN on entry. Then step through the array. If largest is smaller than the number, largest2 becomes largest, then largest becomes the new number (or smaller than or equal if you want to allow duplicates). If largest is greater then the new number, test largest2.

Note that this algorithm scales to finding the top three or four in an array, before it become too cumbersome and it's better to just sort.

Comments

0

//I think its simple like

#include<stdio.h>
int main()

{
int a1[100],a2[100],i,t,l1,l2,n;
printf("Enter the number of elements:\n");
scanf("%d",&n);
printf("Enter the elements:\n");
for(i=0;i<n;i++)
{
    scanf("%d",&a1[i]);
}
l1=a1[0];
for(i=0;i<n;i++)
{
    if(a1[i]>=l1)
    {
        l1=a1[i];
        t=i;
    }
}
for(i=0;i<(n-1);i++)
{
    if(i==t)
    {
        continue;
    }
    else
    {
        a2[i]=a1[i];
    }
}
l2=a2[0];
for(i=1;i<(n-1);i++)
{
    if(a2[i]>=l2 && a2[i]<l1)
    {
        l2=a2[i];
    }
}
printf("Second highest number is %d",l2);
return 0;
}

1 Comment

Instead of simply providing a block of code, could you explain your answer a bit to make it more useful?
0

There is no need to use the Third loop to check the second largest number in the array. You can only use two loops(one for insertion and another is for checking.

Refer this code.

#include <stdio.h>

int main()

{
int a[10], n;

int i;

printf("enter number of elements you want in array");

scanf("%d", &n);

printf("enter elements");

for (i = 0; i < n; i++) {
    scanf("%d", &a[i]);
}

int largest1 = a[0],largest2 = a[0];

for (i = 0; i < n; i++) 
{
    if (a[i] > largest1) 
    {
         largest2=largest1;
         largest1 = a[i];
    }
}

printf("First and second largest number is %d and %d ", largest1, largest2);
}

Hope this code will work for you.

Enjoy Coding :)

Comments

0

Find your second largest number without using any String function:

int array[];//Input array
int firstLargest, secondLargest;
int minNumber = -1;//whatever smallest you want to add here
/*There should be more than two elements*/
if (array_size < 2)
{
    printf("Array is too small");
    return;
}

firstLargest = secondLargest = minNumber;
for (index = 0; index < array_size ; ++index)
{
    //Largest number check
    if (array[index] > first)
    {
        secondLargest = firstLargest;
        firstLargest = array[index];
    }

    //It may not larger than first but can be larger than second number
    else if (array[index] > secondLargest && array[index] != firstLargest)
{
        secondLargest = array[index];
}

//Finally you got your answer
if (secondLargest == minNumber)
{
    printf("No Second largest number");
}
else
{
    printf("Second Largest Number is %d", secondLargest);
}

Comments

0

Here is an answer with a single for loop.

int array[] = { 10, 15, 13, 20, 21, 8, 6, 7, 9, 21, 23 };
const int count = sizeof(a) / sizeof(a[0]);
int lastMaxNumber = 0;
int maxNumber = 0;

for (int i = 0; i < count; i++) {

    // Current number
    int num = array[i];

    // Find the minimum and maximum from (num, max)
    int maxValue = (num > maxNumber) ? num : maxNumber;
    int minValue = (num < maxNumber) ? num : maxNumber;

    // If minValue is greater than lastMaxNumber, update the lastMaxNumber
    if minValue > lastMaxNumber {
        lastMaxNumber = minValue;
    }

    // Updating maxNumber
    maxNumber = maxValue;
}

printf("%d", lastMaxNumber);

Comments

0

If you need to find the largest and second largest element in an existing array, see the answers above (Schwern's answer contains the approach I would've used).

However; needing to find the largest and second largest element in an existing array typically indicates a design flaw. Entire arrays don't magically appear - they come from somewhere, which means that the most efficient approach is to keep track of "current largest and current second largest" while the array is being created.

For example; for your original code the data is coming from the user; and by keeping track of "largest and second largest value that the user entered" inside of the loop that gets values from the user the overhead of tracking the information will be hidden by the time spent waiting for the user to press key/s, you no longer need to do a search afterwards while the user is waiting for results, and you no longer need an array at all.

It'd be like this:

int main() {
    int largest1 = 0, largest2 = 0, i, temp;

    printf("enter number of elements you want in array");
    scanf("%d", &n);
    printf("enter elements");
    for (i = 0; i < n; i++) {
        scanf("%d", &temp);
        if(temp >= largest1) {
            largest2 = largest1;
            largest1 = temp;
        } else if(temp > largest2) {
            largest2 = temp;
        }
    }
    printf("First and second largest number is %d and %d ", largest1, largest2);
}

4 Comments

Downvoting, because although the point is valid, it is not relevant to the question. In some cases arrays DO "magically" appear. An example is DMA transfers in embedded world - hardware does the magic and software is just notified, when the array is filled.
@stiebrs: No, it never magically appears. For your DMA transfer, does the data need to be parsed/validated, and where did the data come from (disk, network, nowhere at all)? If it came from a custom device, why can't the device determine highest and lowest value if that's important?
Because that's life. We use what we have to get the results we need. And often what we have is proprietary and does not have features you need. Hence "magic"
@stiebrs: You're missing the point. Typically you can write code that doesn't have the extra overhead (and sometimes, rarely, you can't); so by explaining "typically you don't need the extra overhead" (and letting people figure out they can't in the rare cases where they can't) you end up with more knowledgeable programmers who are more likely to do it right (when possible) instead of people that always don't do it right.
0

Try Out with this:

    firstMax = arr[0];

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

        if (firstMax < arr[i]  ) {
            secondMax = firstMax;
            firstMax = arr[i];
        }
    }

Comments

0

Although it can be done in one scan but to correct your own code , you must declare largest2 as int.Min as it prevents the largest2 holding the largest value intially.

Comments

-1
#include<stdio.h>

int main()
{
    int a[10];
    int i,b,c;

    printf("Enter ten values : \n");
    for(i=0; i<10; i++)
    {
        scanf("%d",&a[i]);
    }

    b=a[0];

    for(i=0; i<10; i++)
    {
        if(a[i]>b)
        {
            b=a[i];
        }

        else
        {
            b=b;
        }
    }

    if(b==a[1])
    {
        c=a[2];
    }
    else 
    {
        c=a[1];
    }

    for(i=0; i<10; i++)
    {
        if(a[i]>c && a[i]!=b)
        {
            c=a[i];
        }

        else if (b>c)
        {
            c=c;
        }

    }




    printf("Largest number is %d\nSecond largest number is %d",b,c);

}

Comments

-2

If you ever need to find the largest or smallest element in an array, try with bubble sort. Bubble Sort works on simple concept of shifting the biggest element at the end in every pass it does (in case of increasing order). Since you need the first and second largest element in an array, 2 passes of bubble sort will do the trick. The last element will be the largest and the second last element will be second largest. I'm providing you with the link that'll help you understand the bubble sort concept.

http://www.codeido.com/2010/10/bubblesort-written-in-c-with-example-step-by-step/

Hope it helps!!!

2 Comments

This has an average case time complexity of O(n^2), which is pretty terrible for something that can be done in O(n) time.
wouldn't the complexity be O(n)? because we already know that we require only two numbers only. Though when we generalized it, no doubt it'll come to O(n^2), but specifically here shouldn't it be (constant * O(n)) ? Please can anyone explain that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.