C语言 寻找数组中最大和第二大数的程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42401198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:36:51  来源:igfitidea点击:

Program to find largest and second largest number in array

carraysdata-structures

提问by Bhart Kumar

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?

我在很多网站上搜索过这个问题。他们正在通过一些不同的方法来做到这一点。如果我将数组的第一个元素输入为最大,即a[0]. 我认为需要一些小的改变。谁能告诉我?

#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);
}

回答by Schwern

(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.

但这并不是最有效的,因为它是O(n log n),这意味着随着数组变大,比较次数会变快。不太快,比指数慢,但我们可以做得更好。

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.

我们可以在O(n)“线性时间”内完成,这意味着随着数组变大,比较次数以相同的速度增长。

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.

可能有一种更优雅的方法来做到这一点,但这最多可以进行 2n 次比较。充其量它会做 n。

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

请注意,有一个关于如何处理{ 1, 2, 3, 3 }. 应该返回3, 3还是2, 3?我会让你决定并相应地调整。

回答by dave

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!

我认为在 chqrlie 的回答中给出的方法是最好的。也是合乎逻辑的:编写一个程序来找到最大的数字。第二大数字,嗯,这只是之前最大的数字!

回答by Mukesh Burnwal Mike

//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;
}

回答by Nitish Gupta

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 :)

享受编码:)

回答by chqrlie

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?

问题是模棱两可的:如果数组可能包含重复值,您应该找到 2 个最大的不同值还是两个可能相同的最大值?

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.

您的代码似乎表明您想要第一种方法,但如果最大值为 ,则会出现问题a[0]。您应该使用额外的布尔值来跟踪您是否找到了不同的值。

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

您还应该测试不同scanf()调用的返回值并从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;
}

回答by Malcolm McLean

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.

最大和最大 2 在进入时设置为 INT_MIN。然后遍历数组。如果最大小于该数字,则最大 2 变为最大,然后最大成为新数字(如果您想允许重复,则该数字小于或等于)。如果最大大于新数字,则测试最大 2。

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.

请注意,此算法可扩展为查找数组中的前三或前四名,以免变得过于繁琐,最好只进行排序。

回答by Meninx - メネンックス

You need to preserve the index of array members better as they are uniqueHere 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.

请注意,当数组大小为 1 时,值将相同。

回答by Sarat Patel

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);
}

回答by TheTiger

Here is an answer with a single for loop.

这是一个带有单个 for 循环的答案。

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);

回答by Brendan

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).

如果您需要在现有数组中找到最大和第二大元素,请参阅上面的答案(Schwern 的答案包含我会使用的方法)。

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);
}