C如何保持随机变量不重复相同的数字

时间:2018-02-02 21:04:55

标签: c variables random

所以我只是学习C而且我想知道如何防止随rand()函数随机化的变量重复相同的数字。我有一个脚本,它简单地随机化并在for循环中打印一个变量4次。我怎么能这样做,所以变量在每次使用rand()函数后都不会得到相同的数字?

#include <stdio.h>
#include <stdlib.h>
int randomInt;
int main()
{
    srand(time(0));
    for (int i = 0; i < 4; ++i) {
        randomInt = rand() % 4;
        printf("%d\n", randomInt);
    }
    return 0;
}

5 个答案:

答案 0 :(得分:3)

在大多数机器上,int是32位。因此,经过2次 32 迭代后,您确定会得到一些重复(可能之前很久)。

如果您将自己限制在更少的循环中,请考虑例如保留一组以前遇到的随机数(或一些哈希表,或一些二叉树,或其他一些容器)。

对于一个只重复4次的循环,保留一个(最多4-1)先前发出的数字的数组非常简单,而且足够高效。

另请阅读pigeonhole principle

答案 1 :(得分:3)

略有不同的方法。

int set[] = {0, 1, 2, 3 } ;
srand(time(0));
shuffle(set,4);

使用此问题中给出的shuffle算法 https://stackoverflow.com/a/6127606/9288531

答案 2 :(得分:0)

您可以做的是跟踪您已生成的每个号码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hasMyNumberAlreadyBeenGenerated(int number, int generatedNumbers[], int size){

  for(int i = 0; i < size + 1; i++){
    //If you already generated the number, it should be present somewhere in your array
    if(generatedNumbers[i] == number) return 1;
    //If you did not, find the first available space in your array, and put the number you generated into that space
    if(generatedNumbers[i] == 0){
      generatedNumbers[i] = number;
      break; //No need to continue to check the array
    }
  }

  return 0;
}


int main()
{
  int randomInt;
  int generatedNumbers[4];
  //We set "0" in all the array, to be sure that the array doesn't contain unknown datas when we create it
  memset(generatedNumbers, 0x0, sizeof(generatedNumbers));

    srand(time(0));
    for (int i = 0; i < 4; ++i) {
        randomInt = rand() % 4 + 1;
        //As long as the number you generate has already been generated, generate a new one
        while(hasMyNumberAlreadyBeenGenerated(randomInt, generatedNumbers, i) == 1){
          randomInt = rand() % 4 + 1;
        }
        printf("generated : %d\n", randomInt);
    }
    return 0;
}

这种方法的问题在于你无法生成0,因为如果你这样做,你将无休止地循环。 您可以使用malloc()函数使用动态数组绕过此问题。 如果要编写干净的代码,则应使用#define定义要生成的数量。

答案 3 :(得分:0)

我猜你得到相同的数字,因为你在同一秒内多次运行你的程序。如果时间(0)没有改变,您将生成相同的种子并生成相同的随机数。除非您的程序运行得非常快,否则我想使用基于微秒的种子而不是秒可以工作:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    int randomInt;
    int main()
    {
        struct timeval my_microtimer;
        gettimeofday(&t1, NULL);
        srand(t1.tv_sec * my_microtimer.tv_usec);
        for (int i = 0; i < 4; ++i) {
            randomInt = rand() % 4;
            printf("%d\n", randomInt);
        }
        return 0;
    }

答案 4 :(得分:0)

你似乎要问的是一个随机顺序的非随机数字0到3。鉴于此;

int set[] = {0, 1, 2, 3 } ;
int remaining = sizeof(set) / sizeof(*set) ;
while( remaining != 0 )
{
    int index = rand() %  sizeof(set) / sizeof(*set) ;
    if( set[index] > 0 )
    {
        printf( "%d\n", set[index] ) ;
        set[index] = -1 ;
        remaining-- ;
    }
}  

对于非常大的集合,这种方法可能不实用 - 耗尽集合所需的迭代次数是不确定的。