我试图创建一些东西,生成一个没有重复值的随机数组。我已经看过其他的答案了,但似乎没有一个能帮助我理解。我想不出一种方法来实际生成不包含重复项的随机数。下面是我到目前为止尝试的方法:
srand(time(NULL));
int numbers [4];
for (int x=0; x!=4;x++)
{
numbers[x] = 1 + (rand() % 4) ;
printf("%d ", numbers[x]);
}
任何帮助都将不胜感激。
首先,
如果您想要生成一个不重复的随机数组,
假设您要生成一个1000个数字的数组。在最好的情况下,假设您生成了前999个没有重复的数字,最后要做的是生成最后一个数字。得到这个数字的概率是1/1000,所以这几乎要花很长时间才能得到。实际上,只有10个数字会造成很大的麻烦。
最好的方法是通过增量(或严格单调序列)来生成所有的数字,就是将它们洗牌。在这种情况下,将没有重复
这里有一个关于如何用10个数字做的例子。即使有1000个数字它也能工作。
注:Suffle函数来自Jhon Leehey的答案。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle(int *arr, size_t n)
{
if (n > 1)
{
size_t i;
srand(time(NULL));
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
}
int main()
{
int i;
int arr[10];
for (i=0; i<10; i++){
arr[i] = i;
}
shuffle(arr, 10);
for (i=0; i<10; i++){
printf("%d ", arr[i]);
}
}
您首先使用从
然后,您可以得到一个像样的随机数生成器,并正确地为它添加种子
最后,使用rng对元素进行洗牌
住在科里鲁
在某些实现中,
有2种解决方案可供选择:
>
找到一个严格单调(最好是严格递增)的数学序列,并得到它的项作为数组的成员。然后,你可以洗牌你的阵列。结果不会是真正的随机,但是使用rand()也不会。rand()使用了一种类似的技术,这就是为什么我们需要用一些变化的东西来设定种子,比如时间。例如,您可以使用时间来生成序列的第一个元素,使用一个好的序列,您的结果将至少是体面的。注意,序列必须是严格单调的,以避免产生重复项。顺序不必太复杂。例如,如果您将unix时间的模10000作为第一个术语,然后使用recurence(如xi]=xi-1]+3*xi-2)生成其他术语,应该是可以的。当然,您也可以使用更复杂的序列,但是要小心溢出(因为您不能对结果应用模数运算符,因为它不会再增加了)和您想要的位数。