【问题标题】:Generate a random array in C在 C 中生成一个随机数组
【发布时间】:2012-12-10 13:57:58
【问题描述】:

我正在使用 OpenVMS 在 C 中进行开发,我编写了一个代码,将 1001 (0-1000) 个元素数组、1000 (0-999) 个介于 0 和 50 之间的随机数放入其中。代码如下:

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

main(){
    int vet[1000], fre[50];
    int i;

    srand(time(NULL));

    for(i=0;i<1000;i++){
        vet[i]=(rand()%51);
    }

    for(i=0;i<1000;i++){
        printf("%d\n", vet[i]);
    }

    for(i=0;i<1000;i++){
        fre[vet[i]]=fre[vet[i]]+1;
    }

    for(i=0;i<51;i++){
        printf("The number %d  was generated %d times\n", i, fre[i]);
    }
}

当我显示每个数字产生了多少次时,我看到数字 50 有一个很大的数字,有时比其他数字的两倍还多,有人可以帮助我吗?

解决了有效的代码我现在必须使用 srand()

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

main(){
        int vet[1000], fre[51] = {0};
        int i;

        srand(time(NULL));

        for(i=0;i<1000;i++){
                vet[i]=(rand()%51);
        }

for(i=0;i<1000;i++){
printf("%d\n", vet[i]);
}

        for(i=0;i<1000;i++){
                        fre[vet[i]]=fre[vet[i]]+1;
        }

        for(i=0;i<51;i++){
                printf("The number %d  was generated %d times\n", i, fre[i]);
        }
}
[EOB]

谢谢大家

【问题讨论】:

  • rand() PRNG 的质量非常低。如果您需要高质量的 PRN 流,您最好搜索一个更好的,例如Mercenne twister 生成器。如果GSL 在 OpenVMS 上编译,它会附带许多 PRNG。作为最后的手段,OpenVMS 支持drand48 PRNG。在侧节点上,fre 永远不会初始化(全为 0)。
  • 我从来没有用过这些其他的,我今晚会看,谢谢! ;)

标签: c openvms


【解决方案1】:
    int vet[1000], fre[50];


    for(i=0;i<51;i++){
            printf("The number %d  was generated %d times\n", i, fre[i]);
    }

问题 1:您声明 fre 有 50 个元素,但您使用了 51 个。

问题 2:fre 未初始化。

int vet[1000], fre[51] = {0};

应该给你合理的输出。

【讨论】:

  • 为什么是 51?数组不是从 0 开始的?所以当我写 array[50] 是 0,1,2,...,49,50??总数是 51,我不明白如果我写 51 我可以在数组中放入 52 个元素,我错了吗?
  • 不,type array[N]; 声明了一个 N 类型为 type 的元素的数组。有效索引为 0N-1。所以int fre[50]; 为您提供索引 0 到 49。要使用索引 50,您需要 51 个元素。
  • 好的,谢谢你现在工作!!为什么在 50 时给我看这么大的数字?发生了什么?
  • @AlessioMTX 很多事情都可能发生。超出数组边界的读/写是未定义的行为,因此实际发生的情况取决于实现、编译器选项……。可能你刚刚写入并读取了一个未使用的包含垃圾的内存插槽,或者堆栈保护器,或者 reurn 地址,我不知道。
  • Segfault 是一种由于访问冲突等不同原因而导致的错误。在你的情况下,你很有可能得到这个错误。当您遇到此错误时,您的程序将完全崩溃!更多信息在这里:en.wikipedia.org/wiki/Segmentation_fault 每个 C 程序员都遇到过这个错误,至少一次! :)
【解决方案2】:
int vet[1000], fre[50];

您的 vet[] 数组有 1000 个条目,而不是 1001。fre[] 有 50,而不是 51。如果您生成 0 到 50 之间的数字,则需要将 fre[] 声明为 fre[51];

在累积结果之前,您也永远不会清除您的 fre[] 数组。

【讨论】:

  • 数组不是从0开始的?所以当我写 array[50] 是 0,1,2,...,49,50??一共是51,我不明白
  • 数组从零开始,但数字是元素个数,不是最大索引。所以 fre[50] 给出 fre[0] .. fre[49]
  • 通过索引数组的末尾,您正在访问其他对象使用的内存,结果无法预测。
【解决方案3】:

1) 在使用变量之前初始化它们:

int vet[1000] = {0};
int fre[50] = {0};

2) 您正在检查数组大小之外的值:

for(i=0;i<51;i++){  

应该是:

for(i=0;i<50;i++){

您的数组fre[50] 包含fre[0]fre[49] 的元素。所以你希望你的计数从 0 开始,然后转到&lt;50,即 49。

3) 您正在生成超出数组大小的数字:

vet[i]=(rand()%51);

应该是:

vet[i]=(rand()%50); 

rand() % x 将生成一个介于0-(x-1) 之间的数字,如果你的数组大小为50 那么它的元素是0-49,这意味着你需要选择%50 否则你会去分配时超过数组大小:fre[vet[i]]=fre[vet[i]]+1;

4) 请记住,rand() function 会生成伪随机输出,因此它总是有可能不会像您想要的那样“随机”。


编辑
好的,你的评论:2) No because I'm checking also 0 让我觉得你不明白数组是如何工作的:

int fre[50] = {0};

为您提供一个包含 50 个元素的数组。数组的索引从 0 开始,一直到 [number of elements - 1],这样:

first element -->fre[0], fre[1], fre[2], ..., fre[48], fre[49] <-- last element

如果您想记录从 0 到 50 的值,您的数组中需要 51 个元素:

int fre[51] = {0};

所以这两个:

for(int i=0; i<50; i++)    and    for(int i=0; i<51; i++)

从 0 开始,遍历每个元素,但前者适用于 fre[50](从 0 到 49 的 50 个元素),而后者适用于 fre[51](51 个元素,从 0 到 50)

【讨论】:

  • 3) 如果我做 %50 我有从 0 到 49 的数字
  • 2) 不,因为我也在检查 0
  • @AlessioMTX - 是的,您必须这样做,以免您的fre[50] 数组溢出。如果你想做 0-50 的数字,你必须将 fre 的大小增加 1。
  • 我已经按照 Daniel 和 Jason 告诉我的方式完成了 int fre[51]。现在工作。我没有溢出。
  • 37 20 25 24 40 36 0 50 49 27 23 这些是一些数字,在 1000 个元素中,我的最小 0 最大 50
猜你喜欢
  • 1970-01-01
  • 2023-01-03
  • 2013-04-15
  • 2022-01-23
  • 2011-02-08
  • 2019-05-15
  • 1970-01-01
相关资源
最近更新 更多