【问题标题】:Randomizing numbers in C and storing them in an integer array在 C 中随机化数字并将它们存储在整数数组中
【发布时间】:2017-08-27 01:30:21
【问题描述】:

我正在尝试编写一个代码,将 1 到 14 之间的数字随机化(象征一副牌中的一个花色)。代码应将值存储在一个限制为 52 的数组中。每个数字只能存储 4 次(因为一副牌中有 4 个花色)。所以,最后,我应该为 person_a 和 person_b 展示两个随机牌组。

我的问题是 person_a 和 person_b 的随机牌组是相同的。我不知道为什么。我尝试使用 srand() 播种,并使用 rand() 作为随机数。有人可以帮忙吗?

另外,我知道我的代码非常混乱和糟糕。对不起 - 这是我第一次参加 C 课程。下面是代码:

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

#define MAX_DECK 52
#define REPETITIONS 4
#define CARDS_HIGH 14
#define CARDS_LOW 1

int
randomize_check(int value_check, int limit, int cards[])
{
    int count = 0;
    int i = 0;
    for(i=0; i<limit; i++)
    {
        if(cards[i]==value_check)
        {
            count++;
        }
    }
    if(count>REPETITIONS)
    {
        return -1;
    }
    else if (count<=REPETITIONS)
    {
        return 1;
    }
}

int
get_random(void)
{
    int random_number = 0;
    random_number = (rand()%(CARDS_HIGH-CARDS_LOW))+CARDS_LOW;

    return(random_number);
}

int * randomize_deck(void)
{

    static int cards[MAX_DECK];
    int i = 0;
    int randomize = 0;
    int check = 0;

    for (i=0; i<MAX_DECK; i++)
    {
        randomize = get_random();
        cards[i] = randomize;
        check = randomize_check(cards[i], MAX_DECK, cards);
        while((check) == -1)
        {
            randomize = get_random();
            cards[i] = randomize;
            check = randomize_check(cards[i], MAX_DECK, cards);
        }

    }
    return(cards);
}

int
main(void)
{
    srand ( time(NULL) );
    int i = 0, j = 0;

    int *person_a = randomize_deck();
    int *person_b = randomize_deck();

    for (i = 0; i < MAX_DECK; i++) //print_a
    {
        printf( "Cards[a%d]: %d\n", i, *(person_a + i));
    }

    printf("\n");

    for (j = 0; j < MAX_DECK; j++) //print_b
    {
        printf( "Cards[b%d]: %d\n", j, *(person_b + j));
    }

    return(0);
}

【问题讨论】:

  • 为什么你的问题被标记为C++
  • 因为您已将cards 声明为static 数组。
  • @DavidBowling 谢谢!你会建议我如何解决这个问题?
  • 同意,C 或 C++ 很重要。如果您想要 C 解决方案,我会在几分钟内发布答案。
  • 如果您想要替代检查重复项,请考虑利用the Fisher Yates Shuffle

标签: c arrays random


【解决方案1】:

您的问题源于cardsrandomize_deck() 函数中声明为static 数组这一事实。因此,对randomize_deck() 的第一次调用用随机卡片填充这个数组,返回一个指向cards 的指针。然后对randomize_deck() 的第二次调用用新的随机卡片填充相同的static 数组,并返回指向相同static 数组的指针。毕竟,person_aperson_b 都指向同一个 static 数组。

一种解决方案是将randomize_deck() 函数更改为接受数组参数,返回类型为void。此外,最好将数组的大小传递给randomize_deck(),而不是依赖全局常量。请注意,在下面的代码中,我已将数组索引变量更改为类型 size_t,这是一个保证保存任何数组索引的 unsigned 整数类型,并且是数组索引的正确类型。

void randomize_deck(int cards[], size_t deck_sz)
{

    size_t i = 0;
    int randomize = 0;
    int check = 0;

    for (i = 0; i < deck_sz; i++)
    {
        randomize = get_random();
        cards[i] = randomize;
        check = randomize_check(cards[i], deck_sz, cards);
        while((check) == -1)
        {
            randomize = get_random();
            cards[i] = randomize;
            check = randomize_check(cards[i], deck_sz, cards);
        }

    }
}

然后在main() 中,声明两个int 数组,每个玩家一个,并将它们传递给randomize_deck() 函数:

int main(void)
{
    srand ( time(NULL) );
    size_t i = 0, j = 0;

    int person_a[MAX_DECK];
    int person_b[MAX_DECK];

    randomize_deck(person_a, MAX_DECK);
    randomize_deck(person_b, MAX_DECK);

    /* ... */

    return 0;
}

【讨论】:

  • 非常感谢您的回答。当我在做这个问题时,我没有考虑在主函数中声明数组并将它们传递给 randomize_deck()。您对解决方案的解释以及我的代码无法正常工作的原因特别有帮助!我不知道我的代码指向的是同一个数组指针,尽管已经随机化了数组中的卡片。只是一个问题,使用 size_t 而不是像我那样使用全局变量有什么好处吗?
  • 对于数组索引,size_t 是正确的类型; int 可能无法保存所有数组索引(但不太可能,这一点有点迂腐)。至于使用全局常量MAX_DECK,这并没有错,但很多人认为它的风格不好。 1) 使用全局变量通常是不受欢迎的;只有当你有充分的理由时才应该使用全局变量。 2)通过在函数调用中传递数组的大小,代码看起来更清晰。
【解决方案2】:

“...person_a 和 person_b 的随机牌组是一样的。我不知道为什么。”

static int cards[MAX_DECK];

发生这种情况是因为您将整数数组声明为 static

这意味着每次调用函数randomize_deck都会对相同的int数组进行操作并返回相同的数组。**

int * randomize_deck(void) {
    int* cards = malloc(sizeof int) * MAX_DECK); // Instantiate a new and different deck of cards every time the function is called.

    int i = 0;
    int randomize = 0;
    int check = 0;

    /* next steps randomize_deck function */

    return cards; // Now you will return a different deck of cards every time you invoke the function

}

在您的main() 函数中有一个重要步骤需要处理。您无需解除分配在randomize_deck() 中分配的卡的内存。所以,你必须释放person_aperson_b

int main(void)
{
    srand ( time(NULL) );
    int i = 0, j = 0;

    int *person_a = randomize_deck();
    int *person_b = randomize_deck();

    /* ... */
    free(person_a); // You need to free these elements you returned,
    free(person_b);
    return 0;
}

【讨论】:

  • 更好:) +1 用于显示其他选项。顺便说一句,您好像缺少了一个括号。
  • 谢谢你,你打败了我,所以也感谢你(点赞):)
猜你喜欢
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多