计算0(C)以外的不同数字在不同的编译器中输出不同

时间:2018-03-21 19:16:48

标签: c

我试图从输入中找到不等于0的不同数字的数量.n在1-100范围内。阵列中的数字在0-600范围内。 http://codeforces.com/problemset/problem/937/A 对于这个问题,我写了一个代码:

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

int main(void)
{
    int n, count = 0, i;

    scanf("%d", &n);

    int ar[n], ar2[601];
    memset(ar2, 0, 600 * sizeof(int));

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

    for (i = 1; i < 601; i++) {
        if (ar2[i] != 0)
            count++;
    }

    printf("%d",count);
    return 0;
}

对于第一个测试用例(4 1 3 3 2),它在ideone.com的gcc 6.3中输出正确答案3,但在代码强制中使用gcc 5.1输出4。

为什么会发生这种情况,我该如何防止这种情况发生? (我认为这是因为memset,但我不确定。)

3 个答案:

答案 0 :(得分:1)

在确定n的值之前,您正在定义一个大小为n的数组(请注意,scanf之后n的值int n, count = 0, i; int ar[n]; ... 。这是未定义的行为,因此不同的编译器可能会给出不同的结果,甚至在您的机器上启动程序可能会产生不同的结果(包括崩溃)。

而不是

int n, count = 0, i;

scanf("%d", &n);

int ar[n], ar2[601] = { 0 };

ar2

至少应该解决格式错误的数组,并使用0完全初始化memset。你可以摆脱你的date.timezone,无论如何只能初始化600个项目(而不是601个)。

答案 1 :(得分:1)

以下是问题的快速解决方案

#include <stdio.h>

int main()
{
    bool seen_number_before[601] = { false };
    int count = 0;
    seen_number_before[0] = true;

    int n;

    scanf("%d", &n); // Should do error checking here

    for (int i = 0; i < n; ++i) {
       int v;
       scanf("%d", v); // More error checking

       if (!seen_number_before[v]) // Not seen it before
          seen_number_before[v] = true; // Mark it as seen
          ++count;    // Add to the count
       }
     }
     printf("%d\n", count);
     return 0;
}

}

答案 2 :(得分:0)

您的代码中存在一些错误,当未定义n时,来自[n]。 要检查错误,请尝试使用一些有用的选项进行编译:

gcc -Wall code.c -o code -g

-Wall用于全部警告,-g用于valgrind上的调试(用于检查内存泄漏和其他错误的有用工具)。

另外,我建议您正确命名代码中的每个var,这对于大量代码库有帮助。

这是我的解决方案,

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

int main(){
    int n, count = 0;
    scanf("%d", &n);

    int *a = malloc(n * sizeof(int));
    int hash[600] = { 0 };

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

    for(int i=0; i<600; i++){
        printf("%d ", hash[i]);
        if(hash[i] == 1) ++count;
    }

    printf("\n\n%d\n", count);

    return 0;
}

它可以及时优化,只使用一个for和/或内存中创建一个int的hashset,每个int可以存储32位并执行一些按位操作,所以如果第n位为1,则计数++,否则什么都不做。