在C中表现出色-只需重复一次 [英] srand in C - with just one repetition

查看:74
本文介绍了在C中表现出色-只需重复一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to build a memory game and I want to ask how I can generate a randomic number with just one repetition. Like 1-1, 2-2, 3-3. I will paste here my function that I created and tell me if I have to create another function just to create a condition to create just a pair from numbers.

// 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
}

推荐答案

如果您有一个3x2矩阵,应该以随机排列的数字/数字1、1、2、2、3、3填充,那么您可以做类似的事情:

If you have a 3x2 matrix that should be filled with the digits/numbers 1, 1, 2, 2, 3, 3 in some random permutation, then you could do something like:

  1. 分配正确大小的数组(向量),在当前示例中为6.
  2. 在当前示例中使用正确的值-1,1,2,2,3,3填充数组.
  3. 使用适当的技术对数组进行混洗,然后将经过混洗的数据复制到目标2D数组中.
  4. 或者从前6个选项中随机选择一个数字,然后(如有必要)将最后一个数字移动到孔中,然后从其余5个选项中选择下一个数字,依此类推.

您可以使用 Fisher-Yates 混排算法.您可以检入Knuth的副本计算机编程的艺术,第2卷:半数值算法.或者,您可以查找有关堆栈溢出的说明(例如选择一个值的随机组合,之所以选择,是因为我的Google搜索之一也遇到了该值.

You can use the Fisher-Yates shuffling algorithm. You might check in your copy of Knuth The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Or you can look for expositions on Stack Overflow (such as Algorithm to select a single random combination of values, chosen because one of my Google searches also came across it).

从评论中判断,您希望从rand()代理中复制副本,因此这应该可行:

Judging from the comments, you want duplicates from your rand() surrogate, so this should work:

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().您将连续两次获得相同的值.这段代码没有提供重新同步的方法.如果您想要一个,可以很容易地写一个:

Simply call duprand() each time you want a random number. You will get the same value twice in a row. This code doesn't provide a resynchronization method; if you want one, you can write one easily enough:

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


我真正想要的是...

What I really wanted was ...

#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(),您将获得不同的序列.砍砍,以满足您对较小矩阵的要求.

Note that because there's no call to srand(), the permutation is fixed. (You might get a different result from what I show, but running this test multiple times will produce the same result each time on your machine.) Add a call to srand() with an appropriate initialization, and you get different sequences. Hack and chop to suit your requirements for smaller matrices.

这篇关于在C中表现出色-只需重复一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆