【问题标题】:srand in C - with just one repetitionC 中的 srand - 只重复一次
【发布时间】:2015-06-21 23:44:27
【问题描述】:

我正在尝试构建一个记忆游戏,我想问一下我如何可以只重复一次就生成一个随机数。 比如1-1、2-2、3-3。我将在这里粘贴我创建的函数,并告诉我是否必须创建另一个函数只是为了创建一个从数字创建一对的条件。

// function to fulfill the table
void preencher_mesa(int matriz[4][4], int dificuldade)
{
    int i, j;
    int lim_col, lim_linha; // limits of the matriz

    for(i=0; i<4; i++)
        for(j=0; j<4; j++)
            matriz[i][j] = 0;

    if(dificuldade == 1)
    {
        lim_col = 3;
        lim_linha = 2;
    }
    else if(dificuldade == 2)
    {
        lim_col = 4;
        lim_linha = 2;
    }
    else if(dificuldade == 3)
    {
        lim_col = 4;
        lim_linha = 4;
    }

    srand(time(NULL));
    for(i=0;i<lim_linha;i++)
    {
        for(j=0; j<lim_col;j++)
        {
            if(dificuldade == 1) // difficulty == 1
            {
                matriz[i][j] = (rand()%3)+1;
            }
            else if(dificuldade == 2) // difficulty == 2
            {
                matriz[i][j] = (rand()%6)+1;
            }
            else if (dificuldade == 3) // difficulty == 3
            {
                matriz[i][j] = (rand()%8)+1;
            }
        }
    }

    mostrar_mesa(matriz); //showtable
}

【问题讨论】:

  • 这一行:'if(dificuldade == 1)/dificulty ==1' 无法编译
  • 此代码不处理 dificuldate 为 3 的情况
  • 建议:始终使用空格进行缩进。从不制表符。这是因为,根据使用的文字处理器/编辑器(包括 stackoverflow 页面),代码的结果显示会有所不同。而空格(不应该用于代码的可变宽度字体除外)总是相同的
  • 建议:在 main() 函数中尽早调用 srand() 函数,然后永远不要再调用它。
  • 你的意思是你想要一个随机数函数,它连续两次返回相同的数字,然后两次返回另一个数字,等等?比如3、3、75、75、10043、10043、91、91?

标签: c memory random srand


【解决方案1】:

如果您有一个 3x2 矩阵,应该以某种随机排列填充数字/数字 1、1、2、2、3、3,那么您可以执行以下操作:

  1. 分配一个大小合适的数组(向量)——当前示例为 6。
  2. 用正确的值填充数组——当前示例为 1、1、2、2、3、3。
  3. 使用适当的技术对数组进行混洗,然后将混洗后的数据复制到目标二维数组中。
  4. 或从最初的 6 个选项中随机选择一个数字,然后(如有必要)将最后一个数字移入孔中,并从其余 5 个选项中选择下一个数字,等等。

您可以使用Fisher-Yates 洗牌算法。您可以签入您的 Knuth The Art of Computer Programming, Volume 2: Seminumerical Algorithms 副本。或者您可以在 Stack Overflow 上查找说明(例如 Algorithm to select a single random combination of values,之所以选择它是因为我的 Google 搜索之一也遇到了它)。


从 cmets 来看,您希望从您的 rand() 代理中复制,所以这应该有效:

int duprand(void)
{
    static int mode = 0;
    static int value = 0;
    if (mode == 0)
    {
        mode = 1;
        value = rand();
    }
    else
    {
        mode = 0;
    }
    return value;
 }

或者,更简洁:

int duprand(void)
{
    static int mode = 0;
    static int value = 0;
    if (mode == 0)
        value = rand();
    mode = !mode;
    return value;
 }

每次您想要一个随机数时,只需致电duprand()。您将连续两次获得相同的值。此代码不提供重新同步方法;如果你想要一个,你可以很容易地写一个:

void sync_duprand(void)
{
    int i = duprand();
    int j = duprand();
    if (i != j)
       i = duprand();
}

我真正想要的是……

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

extern void shuffle(int *array, int n);
/*
** rand_int() and shuffle() copied verbatim (but reformatted) from
** https://stackoverflow.com/a/3348142 - an answer by Roland Illig
** (https://stackoverflow.com/users/225757/roland-illig).
*/

static int rand_int(int n)
{
    int limit = RAND_MAX - RAND_MAX % n;
    int rnd;

    do
    {
        rnd = rand();
    } while (rnd >= limit);
    return rnd % n;
}

void shuffle(int *array, int n)
{
    int i, j, tmp;

    for (i = n - 1; i > 0; i--)
    {
        j = rand_int(i + 1);
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
    }
}

/* New code - but hardly novel code */
static void dump_matriz(int matriz[4][4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
            printf("  %d", matriz[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    int matriz[4][4];

    int *base = &matriz[0][0];
    for (int i = 0; i < 8; i++)
    {
        *base++ = i + 1;
        *base++ = i + 1;
    }

    printf("Before:\n");
    dump_matriz(matriz);

    shuffle(&matriz[0][0], 16);

    printf("After:\n");
    dump_matriz(matriz);

    return 0;
}

样本输出:

Before:
  1  1  2  2
  3  3  4  4
  5  5  6  6
  7  7  8  8
After:
  1  7  8  6
  6  2  5  8
  2  4  7  3
  3  5  1  4

请注意,因为没有调用srand(),所以排列是固定的。 (您可能会得到与我展示的结果不同的结果,但多次运行此测试将在您的机器上每次都产生相同的结果。)添加对 srand() 的调用并进行适当的初始化,您会得到不同的序列。破解并切碎以满足您对较小矩阵的要求。

【讨论】:

  • 在阅读了这个问题后,我认为 OP 是在询问如何创建一个随机函数,该函数连续两次返回每个数字,例如 3、3、75、75、10043、10043、91, 91 等。我已经为此写了一个答案,但在阅读了你的答案后,我不确定我是否正确解释了这个问题(因此我是否应该发布我的答案)......你怎么看?
  • 连续两次返回相同的数字并不是什么大成就,是吗?您只需使用该号码两次。因此,我认为要求更复杂。
  • 是的@ace,你应该这样做!因为我还在想办法实现这个目标!
  • @LuccaMello:假设您想要从您的rand() 复制,那么:int duprand(void) { static int mode = 0; static int value = 0; if (mode == 0) { mode = 1; value = rand(); } else { mode = 0; } return value; } 应该可以完成这项工作。每次您想要一个随机数时,只需致电duprand()。您将连续两次获得相同的值。此代码不提供重新同步方法;如果你想要一个,你可以很容易地写一个:void sync_duprand(void) { int i = duprand(); int j = duprand(); if (i != j) i = duprand(); }.
  • 我现在需要的是假设我有 8 对数字,例如:(1,1)(2,2)(3,3),(4,4),( 5,5),(6,6),(7,7),(8,8) 并且我需要在表格中得到这个数字随机播放,我希望这个数字在这个表格中获得不同的位置(矩阵 [ 4][4])。 1 级 - 简单 - 此表中只有 3 对随机数字,2 级 - 中等 4 对,3 级 - 困难 - 8 对 @Jonathan Leffler
猜你喜欢
  • 2021-11-25
相关资源
最近更新 更多