1

我正在尝试在 1 到 10 之间生成 10 个唯一的随机数。我不断收到重复的数字。有人可以告诉我问题是什么吗?我的代码中缺少什么或需要修复什么?谢谢!

students[0].id = rand() % 10 + 1;
for (int i = 1; i < 10; i++)
{
    students[i].id = rand() % 10 + 1;
    for (int j = 0; j < i; j++)
    {
        if (students[i].id == students[j].id)
        {
            students[i].id = rand() % 10 + 1 ;
        }
    }
}

for (int i = 0; i < 10; i++)
{
    printf("%d\n", students[i].id);
}
4

9 回答 9

2

该函数rand()不能保证生成唯一的随机数。此外,您限制范围的方式(mod 10)特别糟糕,可能会产生许多重复项。

生成序列的最简单方法可能是将包含 10 个值的数组从 1 随机排列到 10。

于 2013-04-11T05:45:46.467 回答
2
if (students[i].id == students[j].id)
        {
            students[i].id = rand() % 10 + 1 ;
        }

在这一行中,您可能会得到重复。

如果 students[i].id & students[j].id = 5 意味着它会变成真的。但在这一行students[i].id = rand() % 10 + 1 ;,你可能会再次得到5

您可以使用此代码代替上面的代码。

students[0].id = rand() % 10 + 1;
for (int i = 1; i < 10; i++)
{
    students[i].id = rand() % 10 + 1;
    for (int j = 0; j < i; j++)
    {
        if (students[i].id == students[j].id)
        {
           i--;
           break;
        }
    }
}
于 2013-04-11T05:51:53.460 回答
1

rand()本质上是随机的,所以不能保证给你独特的结果。你需要做这样的事情-跟踪到目前为止遇到的所有号码并打电话给你,rand()直到你找到唯一的号码

于 2013-04-11T05:45:57.567 回答
0

试试这个:用while替换if。我希望你得到你的答案。

学生[0].id = rand() % 10 + 1;

for (int i = 1; i < 10; i++)

{

students[i].id = rand() % 10 + 1;
for (int j = 0; j < i; j++)
{
    while (students[i].id == students[j].id)
    {
        students[i].id = rand() % 10 + 1 ;
    }
}

}

for (int i = 0; i < 10; i++)

{

printf("%d\n", students[i].id);

}

于 2013-04-11T05:59:21.593 回答
0

如果 RAND_MAX(通常为 32767)不能被 10 整除会怎样?您可能比 8 和 0 更频繁地获得 1 和 7 之间的值。这是一种偏差。

我建议丢弃任何大于或等于 32760 (或更确切地说,RAND_MAX - RAND_MAX % 10)的值,并使用除法运算符来构造您的随机数:

int x;
do {
    x = rand();
} while (x >= RAND_MAX - RAND_MAX % 10);
x /= RAND_MAX / 10;

你会从中看到相当大的改进;事实上,这似乎是你最重要的偏见。但是,您获得的值的分布仍然不需要是均匀的。使用查找表丢弃您之前选择的任何值:

int selected[10] = { 0 };
for (int i = 0; i < 10; i++) {
    int x;
    do {
        x = rand();
    } while (selected[x / RAND_MAX / 10] || x >= RAND_MAX - RAND_MAX % 10);
    x /= RAND_MAX / 10;
    selected[x] = 1;

    student[i].id = x;
}

for (int i = 0; i < 10; i++) {
    printf("student[%d].id: %d\n", i, students[i].id);
}
于 2013-04-11T06:46:06.697 回答
0

随机并不意味着“没有重复”。

于 2013-04-11T05:45:59.503 回答
0

你需要递归

public static void main(String[] args)
{
    System.out.println(generateRandomNumbers(10, new ArrayList<Integer>()));
}

private static List<Integer> generateRandomNumbers(Integer maxLimit, List<Integer>    randomNumberList)
{
    for (int i = 0; i < maxLimit; i++)
    {
        Integer tempRandom = new Random().nextInt(10);
        if (randomNumberList.contains(tempRandom))
            generateRandomNumbers(1, randomNumberList);
        else
            randomNumberList.add(tempRandom);
    }
    return randomNumberList;
}
于 2013-04-11T06:11:26.420 回答
0

输入此 if 子句if (students[i].id == students[j].id)并修改students[i].id 后,您需要再次检查重复项。

于 2013-04-11T05:47:31.550 回答
0

我认为您想在不更换的情况下进行采样。您可以将索引存储在数组中,随机选取一个并同时将其从数组中删除。

这样下次画的时候就不会重复了。

于 2013-04-11T06:09:16.817 回答