【问题标题】:check if the numbers already given in a array检查数组中是否已经给出了数字
【发布时间】:2022-01-01 03:08:05
【问题描述】:

这是我正在学习的书中的一个程序。我不明白这个程序如何跟踪已经被占用的数字。这本书很简洁,我不明白他们的解释。有人可以帮我更好地理解这段代码的细节吗?特别是代码注释中指出的部分。

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

const int maxrange = 49;
const int maxballs = 6;

int rnd(int range);
void seedrnd(void);

int main()
{
    int numbers[maxrange];
    int i, b;

    printf("L O T T O  Z I E H U N G E N\n");
    seedrnd();

    for (i = 0; i < maxrange; i++)
    {
        numbers[i] = 0;
    }
    printf("Drueken sie eingabe fuer die Zahlen dieser Woche: ");
    getchar();

    printf("Es geht los\n");

    //This is the part I am stuck at: where the numbers in the array
    //are checked to see if the number has been used

    for (i = 0; i < maxballs; i++);
    {
        do
        {
            b = rnd(maxrange);
        } while (numbers[b - 1]);
        numbers[b - 1] = 1;
        printf("%i ", b);
    }

    printf("\n\nViel Glueck\n");
    return 0;
}

int rnd(int range)
{
    int r;
    r = rand() % range + 1;
    return (r);
}

void seedrnd(void)
{
    srand((unsigned)time(NULL));
}

【问题讨论】:

  • 提示:while(numbers[b - 1]);while(numbers[b - 1] != 0); 相同
  • 我会采取不同的做法:每选择一个数字,我都会将maxrange(更准确地说:重复!)减一。然后你遍历数组,每个数字小于或等于新的数字,你增加后一个数字。但是,到目前为止选择的数字需要进行排序——只要已经选择的数字更大,您就可以通过排序新的数字来实现。这样,您可以计算出与要选择的球一样多的随机数。
  • 顺便说一句:对rand 的结果进行模计算提供了相当差的分布——可能只是玩玩而已,对于更严肃的应用程序你应该更喜欢rand() * (range + 1) / RAND_MAX——取决于@987654327 的大小@ 和 RAND_MAX 你可能需要考虑溢出。
  • 作者应该为numbers 使用更好的名称 - 例如indexTaken.
  • 意见和风格各不相同。我有点惊讶,还没有人使用“旗帜”这个词。这就是 numbers 的含义 - 一组标志,指示选择了哪些数字。

标签: arrays c random


【解决方案1】:

循环的目的是确保您获得maxballs 唯一编号。这是通过使用数组 numbers 来“记住”已经使用过的数字来完成的。

思路如下。

首先数组numbers 用零填充。

然后选择一个随机数。例如 2。while (numbers[b - 1]); 停止,因为 numbers[1] 为零。

然后numbers[1]在这里设置为1 numbers[b - 1] = 1;

然后选择下一个随机数。如果再次应该是 2,它将被拒绝,因为现在 numbers[1] 不为零,所以 while (numbers[b - 1]); 将导致选择另一个随机数。

通过这种方式,您将获得maxballs 唯一编号。

正如@ikegami 所评论的,值得一提的是,生成唯一数字随机序列的更好方法是 Fisher-Yates shuffle。在这里阅读更多:https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

【讨论】:

  • 请注意,这是一种不好的方法。最好使用部分Fisher-Yates shuffle。它不会占用任何额外的内存,也不存在不断获取相同数字的问题。
  • @ikegami 完全同意 Fisher-Yates 是获得唯一随机数的更好方法。对于这种特定情况,“试错”方法可能不是主要问题,因为 OP 只需要 49 个可能数字中的 6 个唯一数字。但是,我还是应该提到费舍尔-耶茨。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多