c - 在c中生成随时间变化的简单随机数

标签 c random

我正在使用这个功能:

int rand2(int lim)
{
        static long a = 1;  // could be made the seed value
        a = (a * 32719 + 3) % 32749;
        return ((a % lim) + 1);
}

要获取随机数堆栈,它工作正常,但每次启动此函数时,我都会有相同的数字堆栈,因此我想使用 time() 系统函数每次都有不同的堆栈

int rand3(int lim, int dat_time)
{
  static int a = dat_time; // could be made the seed value                                                       
  a = (a * 32719 + 3) % 32749;
  return ((a % lim) + 1);
}

然后我给出一次我的计算机的 time(),因为变量 a 是静态的

int             main()
{
  int           rd;
  time_t        timee;
  int           seed;

  timee = 0;
  timee = time(timee);
  seed = timee;
  while(42)
    {
      rd = rand3(52, seed);
      printf("%d\n", rd);
      getchar();
    }
}

然后我收到一个错误,说 dat_time 不是常量,但由于我使用过一次,所以我不明白为什么

最佳答案

静态存储持续时间变量在任何代码开始运行之前初始化,并且必须使用可在编译时计算的表达式进行初始化。

这意味着不要使用在运行时才能确定的变量来初始化它们。如果您删除了static,错误就会消失,但每次调用随机数生成器时您都将重新播种它。

在请求第一个随机数之前,您确实应该初始化随机种子一次(如 C 标准库中的 srand()/rand() 所示),并且然后使用随机函数循环遍历序列中的值。这可以通过以下方式完成:

int rand4 (int numLimit) {
    static int randSeed, needsInit = 1;
    if (needsInit) {                      // This bit only done once.
        randSeed = time(0);
        needsInit = 0;
    }
    randSeed = (randSeed * 32719 + 3) % 32749;
    return (randSeed % numLimit) + 1;
}

一个typical implementation srand()/rand() 的思路是:

// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

在其自己的源文件中,以便从 View 中隐藏下一个种子。这遵循预期的行为,即在不先调用 srand() 的情况下调用 rand() 与调用 srand (1) 的效果相同。


而且,根据您的评论,您需要一定数量的调用来生成从 1 到 52 的所有数字,听起来您正在使用它来生成一副随机的牌。如果是这种情况,有一个比生成随机数并丢弃您已经见过的数字更好的方法。

随着剩余牌组的尺寸变得越来越小,该解决方案很快就会恶化。对于 O(1) 时间和空间解决方案,请使用 Fisher-Yates 洗牌。

基本算法是使用未排序的列表,并简单地将最终元素与随机选择的元素交换,从而将列表大小减少一:

dim n[N]                  // gives n[0] through n[N-1]

for each i in 0..N-1:     // initialise them to their indexes
    n[i] = i              // (use i+1 for 1-10 instead of 0-9).

nsize = N                 // starting pool size
do N times:
    i = rnd(nsize)        // give a number between 0 and nsize-1
    print n[i]
    nsize = nsize - 1     // these two lines effectively remove the used number
    n[i] = n[nsize]

由此生成的数字是:

<------ n[] ------>
0 1 2 3 4 5 6 7 8 9  nsize  rnd(nsize)  output
-------------------  -----  ----------  ------
0 1 2 3 4 5 6 7 8 9     10           4       4
0 1 2 3 9 5 6 7 8        9           7       7
0 1 2 3 9 5 6 8          8           2       2
0 1 8 3 9 5 6            7           6       6
0 1 8 3 9 5              6           0       0
5 1 8 3 9                5           2       8
5 1 9 3                  4           1       1
5 3 9                    3           0       5
9 3                      2           1       3
9                        1           0       9

关于c - 在c中生成随时间变化的简单随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19133275/

相关文章:

javascript - 六边形/形状中的随机点

c - 数组 C 编程中的随机探索

c - 尝试在单链表中的某个位置之后插入节点,但它会在之前插入它

c++ - 如何修复 Sentry 中缺少的 CSRF token

php - 伪随机 URL 生成

PHP 生成一个唯一的字符串

c - 当 actual 和 extern 类型不同时会发生什么?

c - 如何在 unix 中解析管道或重定向运算符?

python - 使用函数时保持获得相同的随机值

random - sparql:为每个节点随机选择一个连接