提问者:小点点

无重复的随机阵列生成


我试图创建一些东西,生成一个没有重复值的随机数组。我已经看过其他的答案了,但似乎没有一个能帮助我理解。我想不出一种方法来实际生成不包含重复项的随机数。下面是我到目前为止尝试的方法:

srand(time(NULL));
int numbers [4];

for (int x=0; x!=4;x++)
{
    numbers[x] = 1 + (rand() % 4) ;
    printf("%d ", numbers[x]);
}

任何帮助都将不胜感激。


共3个答案

匿名用户

首先,生成随机数,但不是没有重复的。

如果您想要生成一个不重复的随机数组,方法根本不起作用。

假设您要生成一个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对元素进行洗牌

住在科里鲁

在某些实现中,不能正常工作(尤其是windows上的gcc),您必须使用另一个种子,即当前时间

匿名用户

有2种解决方案可供选择:

>

找到一个严格单调(最好是严格递增)的数学序列,并得到它的项作为数组的成员。然后,你可以洗牌你的阵列。结果不会是真正的随机,但是使用rand()也不会。rand()使用了一种类似的技术,这就是为什么我们需要用一些变化的东西来设定种子,比如时间。例如,您可以使用时间来生成序列的第一个元素,使用一个好的序列,您的结果将至少是体面的。注意,序列必须是严格单调的,以避免产生重复项。顺序不必太复杂。例如,如果您将unix时间的模10000作为第一个术语,然后使用recurence(如xi]=xi-1]+3*xi-2)生成其他术语,应该是可以的。当然,您也可以使用更复杂的序列,但是要小心溢出(因为您不能对结果应用模数运算符,因为它不会再增加了)和您想要的位数。