所以我只是学习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;
}
答案 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-- ;
}
}
对于非常大的集合,这种方法可能不实用 - 耗尽集合所需的迭代次数是不确定的。