C在数组中找到第二大数字

时间:2013-10-17 22:45:46

标签: c arrays numbers

正如标题所说,我必须在数组中找到第二大数字,如果该数组中的每个数字相等,我应该写它是-∞。我写了这个,任何人都可以检查一下,看看我是否可以更好地优化它?这个数组只是一个例子,它应该是x [1 ... n],但由于我必须将它重写为伪代码,我把那个作为一个例子

#include <stdio.h>
int main()
{
    int x[7]={90,90,78,41,21,27,35};
    int i, max, secmax, y;
    secmax=0;
    max=x[0];
    for(i=1;i<=7;i++)
        {
        if (x[i]>max)
            {
            secmax=max;
            max=x[i];
            }
        else if (x[i]>secmax&&x[i]<max)
                {
            secmax=x[i];
            }
        }

    for(i=0;i<7;i++)
        if(x[i]==x[i+1])
            y++;

    if (y==6)
        printf("sec max to minus nieskonczonosc \n");
    else 
        printf("max to %d a secmax to %d\n",max,secmax);
    return 0;
}

3 个答案:

答案 0 :(得分:3)

通过将secmax初始设置为负无穷大,可以避免对整个阵列进行最后一次扫描。这样它将始终具有正确的值。

此外,您的代码中存在错误:i<=7应替换为i < sizeof(x)/sizeof(x[0])。否则,x[i]会给你一个段错误。

答案 1 :(得分:3)

以下是您可以做的事情:

int get_second_max(int *x, size_t n)
{
    int max[2] = {-MAX_INT,-MAX_INT};
    int i = 0, same = 1;
    if (NULL == x || 0 == n)
        return -MAX_INT;

    max[0] = x[0];
    max[1] = x[0];
    for(i = 1; i < n; i++) {
        /* same is used to check 
         * if the array contains 
         * the same number all along.
         */
        same &= (x[i] == x[i-1]);
        /* At the i-th iteration :
         * -> max[0] stores the maximum value
         * -> max[1] stores the second maximum value
         */

        /* We hit a new max value, we must :
         * 1. Update the second max value with the current max value
         * 2. Update the current max value with the new max we found
         */
        if(x[i] > max[0]) {
            max[1] = max[0];
            max[0] = x[i];
        } else if(x[i] > max[1]) {
            max[1] = x[i];
        }
    }
    if(same) {
        return -MAX_INT;
    } else {
        return max[1];
    }
}

答案 2 :(得分:0)

我做了一些修改并添加了一些评论。在代码下面讨论。

#include <limits.h> // for INT_MIN macro
#include <stdio.h>
int main()
{
    // Let the compiler count length of array.
    // -- declare "x[]", no need to specify length
    const int x[] = { 90, 90, 78, 41, 21, 27, 35 };
    // -- use sizeof() math to find length of array
    // -- use const int rather than #define so debugger can see value
    const int len = sizeof(x) / sizeof(x[0]);
    int i, max, secmax, same_count;

    if (0 == len)
    {
        // zero-length list: return INT_MIN
        printf("sec max to minus nieskonczonosc: %d\n", INT_MIN);
        return 0;
    }

    secmax = max = INT_MIN;

    same_count = 0;

    // start loop at 0
    for(i = 0; i < len; ++i)
        {
        // We'll use the same idea you originally used to find if all values were
        // the same, but do it as part of the same loop.  No need to loop over
        // the values twice.  For a short list, looping twice is not a big deal,
        // but for really large data sets it will save lots of time to do it this way.
        same_count += (x[0] == x[i]);

        if (x[i]>max)
            {
            // Found value greater than current max; shift max down to secmax
            // and save new max value.
            secmax=max;
            max=x[i];
            }
        else if (x[i]>secmax && x[i]<max)
            {
            // It wasn't greater than max, but is greater than secmax.
            // Save new secmax value.
            secmax=x[i];
            }
        }

    if (len == same_count)
        printf("sec max to minus nieskonczonosc: %d\n", INT_MIN);
    else 
        printf("max to %d a secmax to %d\n",max,secmax);

    return 0;
}

我们无法改善运行时间。您的代码已经在直接找到所需的值。

我们可以做的一件事就是通过在第一个循环中完成它的工作来摆脱你的第二个循环。

@Rerito的回答改变了算法:不是计算有多少值是相同的,而是查看计数是否与长度匹配,那么该答案以1位开始并使用按位&#34;和&#34;与价值比较。如果比较失败,则比较结果将为零,并且按位&#34;和&#34;值为0的结果为0.因此,如果比较失败,则初始1位清零为0位,当循环结束时,如果仍然设置该1位,则每个值必须为相同。

我保留了计算多少个值相同的基本算法,然后检查计数是否与长度匹配。我重命名了计数变量,因为名称y没有信息,我将计数更新移动到第一个循环内部(然后摆脱了第二个循环),我重新编写了代码,以便您可以更改数组值它应该只是工作。

没有连接&#34;魔法&#34;这是不好的做法。通过代码散布的值。您的原始代码在三个位置都有一个7和一个6 ...因此当有人更改数组的长度时,它会为一个错误打开。我的代码让C编译器计算数组中有多少个值,设置一个常量(len),然后专门使用该常量。因此,您只需添加或删除数组中的值,更改后的代码仍然可以正常工作。

编辑:@sds写道:&#34;你可以通过将secmax最初设置为负无穷大来避免整个阵列的最后一次扫描。这样它将始终具有正确的值。&#34;

哇,哇,他是对的!我们所要做的就是将secmax设置为我们想要返回的值,如果每个值都相同,因为当代码看到的值小于{时,代码只会写入secmax。 {1}},如果每个值都相同,那么max将永远不会改变。