2011-11-01 84 views
-1

我想产生一个随机数的随机数,但它不应该是一个特定的编号。所以我传递的数字不应该是随机数以及它必须生成的范围到函数中,并且如果生成的随机数是不应该生成的数字,我将重新调用函数,所以这个花了很长时间,导致我的程序被终止。我正在使用下面的代码,让我知道如何有效地生成随机数,而无需等待很长时间,甚至无需重新调用函数。生成用C

这里等级-1是传递给它的数量,这不应该产生和尺寸1是数字,表示最大允许值

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); 

} 

回答

5

标准警告的范围适用于这里:您要拨打srand刚好在初始化期间一次,并且从不再次调用它。

至于不产生rank1,我以为我会减少1的范围内,然后,如果你得到的结果为> = rank1,添加一个到它在rank1创建一个“洞”。

1

几点意见:

  1. 你不需要srand()每次。无论如何,在程序运行过程中,你不应该多播一次。把这个早点放在你的main()方法中,或者在这里创建一个静态标志,并且只播种一次。
  2. 因为time()给秒,srand将重新播种发电机它同第二,它(尤其是这个递归)可能是几千到数百万次期间就是所谓的相同状态每一次,返回相同的随机数。请注意,递归约5,000级后,递归会产生堆栈溢出(可能是您的问题的一部分)。因此:
  3. 递归更改为while循环。
  4. 什么样的规模是你rank1size1会是?如果,例如size1是RAND_MAX和rank1是零,你应该没问题。但是,如果size1为1且rank1为0,则永远不能返回。

这可能是一个更好的实现:

  1. 有更多... ...简洁的方式来写这个循环,但这:

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

    这个代码现在评论方式应该是最容易理解的。

  2. 你或许应该改变断言返回零,如果你还没有学会他们没有。
  3. 你也可以产生size1 - 1号码,将它们分割,以便跳过rank1,但我会离开代码作为练习读者。
+0

这是什么???断言 – user1020111

+0

如果条件不成立,他们会停止程序。非常有用的调试,但正如我所说,在你的水平,你应该改变'assert(x)'为'if(!(x))返回0;'或者甚至返回-1并检查代码中的错误情况调用这个方法。 – Kevin