在C中生成一个随机数

时间:2011-11-01 02:33:38

标签: random

我正在尝试生成一个随机数,但它不应该是一个特定的数字。所以我传递的数字不应该是随机数和必须为函数生成的范围,如果生成的随机数是不应该生成的数字,我重新调用该函数,所以这个花了很长时间,导致我的计划终止。我使用下面的代码,让我知道如何有效地生成随机数而无需等待很长时间甚至没有重新调用该函数。

这里rank1是传递给它的数字,不应该生成它,size1是数字,表示最大可接受值的范围

int rgenerator(int rank1, int size1)
{

    int iseed, k;
    time_t seconds;
    time(&seconds); 
    iseed=(unsigned int) seconds;

    srand(iseed);

    k=rand()%size1;

    if(k!=rank1)
        return k;
    else 
        rgenerator(rank1,size1);

}

2 个答案:

答案 0 :(得分:5)

标准警告适用于此:您希望在初始化期间完全一次调用srand,并且永远不要再次调用它。

至于不生成rank1,我想我只是将范围缩小1,然后如果得到的结果是> =到rank1,则添加一个来创建一个rank1处的“洞”。

答案 1 :(得分:1)

一些评论:

  1. 您每次都不需要srand()。无论如何,在程序运行期间你真的不应该多播一次。把它放在你的main()方法的早期,或者在这里创建一个静态标志,只播种一次。
  2. 因为time()给出了秒数,srand每次在同一秒内调用时,都会将生成器重新播种到相同的状态(特别是对于此递归)可能是数千到数百万次,返回相同的随机数。请注意,递归将在〜5,000级递归后产生堆栈溢出(可能是您的问题的一部分)。因此:
  3. 将递归更改为while循环。
  4. 您的rank1size1的尺寸是多少?如果,例如size1是RAND_MAX,rank1为零,你应该没问题。但是,如果size1为1且rank1为0,则永远不会返回。
  5. 这可能是更好的实施方式:

    int rgenerator(int rank1, int size1) {
        // Prevent division by zero.
        assert(size1 > 0);
    
        // Prevent infinite loops from no valid returns
        assert(rank1 != 0 || size1 > 1);
    
        int randnum;
        do {
            randnum = rand() % size1;
        } while (randnum != rank1);
    
        return randnum;
    }
    

    现在对此代码发表评论:

    1. 还有更多......简洁......编写循环的方法,但这种方式应该是最容易理解的。
    2. 如果您尚未学习它们,您应该将断言更改为零。
    3. 您还可以生成size1 - 1个数字并将其拆分以跳过rank1,但我会将该代码作为练习留给读者。