在不排序的情况下找到数组中的第二大元素

时间:2018-08-12 22:55:33

标签: c arrays

我知道将两个变量初始化为INT_MIN的单一遍历方法。但是我的问题是为什么我们将两个变量初始化为INT_MIN,这里INT_MIN的目的是什么?

为什么不能像我在下面的代码中那样将两个变量初始化为其第一个元素?因为当我手动检查代码时,我没有发现任何错误。那么为什么代码不能正常运行?

#include <stdio.h>

int main(void) {
    int x[10];
    int i, n;
    int first = x[0];
    int second = x[0];

    printf("Input the size of array :");
    scanf("%d", &n);

    printf("Input %d elements in the array :\n", n);
    for (i = 0; i < n; i++) {
        printf("x[%d]: ", i);
        scanf("%d", &x[i]);
    }

    for (i = 0; i < n; ++i) {
        if (first < x[i]) {
            second = first;
            first = x[i];
        } else
        if (x[i] > second && x[i] != first) {
            second = x[i];
        }
    }

    if (second == first)
        printf("There is no second largest element\n");
    else
        printf("\nThe Second largest element in the array is: %d", second);

    return 0;
}

5 个答案:

答案 0 :(得分:3)

我在发现一些问题的地方添加了一些评论。希望我能解决所有问题。下面的代码。

#include <stdio.h>

int main(void) {
    // int x[10]; I moved this to under where you ask the user for the array size.
    int i, n;
    // int first=x[0]; This should be written after the user has inputted their numbers. Because what is in x[0]? user hasn't entered anything yet
    // int second=x[0]; Same reason as ^

    printf("Input the size of array :");
    scanf("%d",&n);
    int x[n]; // This should be here because you asked the user what the size of the array is.

    printf("Input %d elements in the array :\n",n);
       for(i=0; i<n; i++)
        {
          printf("x[%d]: ", i);
          scanf("%d", &x[i]);
        }
    // You should put your first and second int's here
    int first=x[0]; 
    int second=x[0];

    for (i=0; i<n ; ++i)
     {
        if (first<x[i])
        {
            second = first;
            first = x[i];
        }

        else if (x[i] > second && x[i] != first)
         {
            second = x[i];
         }
    }

    if (second == first)
        printf("There is no second largest element\n");
    else
        printf("\nThe Second largest element in the array is: %d", second);


    return 0;
}

答案 1 :(得分:3)

您的代码中存在几个问题:

  • 数组x的长度为10,但在将firstsecond设置为其第一个元素的值时未初始化。
  • 您不测试scanf()的返回值,从而在输入失败的情况下导致不确定的行为。
  • 在将值读入n之前,您不会测试10的值是否小于或等于x
  • 您需要使用特殊情况n <= 0,因为不会将任何值读入x

这是修改后的版本:

#include <stdio.h>

int main(void) {
    int x[10];
    int i, n, first, second;

    printf("Input the size of array :");
    if (scanf("%d", &n) != 1 || n < 0 || n > 10) {
        printf("invalid input\n");
        return 1;
    }

    if (n <= 0) {
        first = second = 0;
    } else {    
        printf("Input %d elements in the array:\n", n);
        for (i = 0; i < n; i++) {
            printf("x[%d]: ", i);
            if (scanf("%d", &x[i]) != 1) {
                printf("invalid input\n");
                return 1;
            }
        }
        first = second = x[0];
        for (i = 1; i < n; ++i) {
            if (first < x[i]) {
                second = first;
                first = x[i];
            } else
            if (x[i] > second && x[i] != first) {
                second = x[i];
            }
        }
    }

    if (second == first)
        printf("There is no second largest element\n");
    else
        printf("\nThe Second largest element in the array is: %d\n", second);

    return 0;
}

关于将firstsecond初始化为INT_MIN并且循环从i = 0开始的另一种实现,窍门是INT_MIN是最小的int的值,因此first会将<=与数组的所有值进行比较,因此不会遮盖较小的值。对于在传递空数组时在数组中找到最大值的函数,它也是一个很好的默认返回值。

对于您的案例研究,INT_MIN方法不起作用,该算法将在具有单个重复值的数组上失败:在扫描结束时,first将被设置为值和second仍为INT_MIN

  • 测试first == second将产生等于INT_MIN的第二个最大值,这是不正确的。
  • 测试second == INT_MIN以确定所有值是否相同也将是不正确的,因为具有值{ 1, INT_MIN }的数组的确会具有等于INT_MIN的第二个最大值。

您的方法可以正常工作,并且替代方法将需要以不同的方式编写,并带有一个额外的变量。确实,this article中提出的解决方案是不正确的,this onethis onethis one也是不正确的,并且在互联网上出现了无数更多的随机代码。

答案 2 :(得分:1)

int first=x[0];
int second=x[0];

x尚未初始化。

答案 3 :(得分:0)

如果找不到第二大元素,则打印-1。

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

int findNotSame(long long int a[],long int n)
{
    long long int temp = a[0];
    int flag = 0;
    long int i;
    for(i=0;i<n;i++)
    {
        if(a[i]!=temp)
            return 1;         
    }
    return 0;
}

long long int findMax(long long int a[],long int n)
{
    long  int i;
    long long int max = a[0];
    for(i=0;i<n;i++)
    {
        if(a[i]>max)
            max =  a[i];
    }
    return max;
}

int main() {

    long int i,j,n;
    scanf("%ld",&n);
    long long int a[n];
    if(n<2)   //There cannot be scond largest if there;s only one(or less) element.
    {
        printf("-1");
        return 0;
    }
    for(i=0;i<n;i++)  //Read elements.
        scanf("%lld",&a[i]);


    if (!findNotSame(a,n))   //Check if all the elements in array are same if so, then -1.
    {
        printf("-1");
        return 0;
    }

    long long int max = findMax(a,n);  //Find maximum element(first).

    long long int max2 = -999999999999999; //Initialize another max which will be the second maximum.

    for(i=0;i<n;i++)  //Find the second max. element.
    {
        if(a[i]>max2 && a[i] != max)
            max2 =  a[i];
    }
    if(max == max2) //Incase if second max(largest) is same as maximum
        max2 = -1;

    printf("%lld",max2);
    return 0;
}

答案 4 :(得分:0)

import ast
input_str = input()
input_list = ast.literal_eval(input_str)
if len(input_list)<2:
    print("not present")
else:
    i=input_list[0]
    j=i
    for index_val in input_list[1:]:
        if i<index_val:
            j=i
            i=index_val
        elif index_val>j and index_val!=i:
            j=index_val
        elif i==j and index_val<j:j=index_val
    if i==j:
        print("not present")
    else:
        print(j)