C++实现生成1—10000之间的10000个不重复的随机数

本文介绍了一种使用C++实现的随机数生成及洗牌算法,通过伪随机数生成器和数组操作实现了均匀分布的随机数洗牌效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int MaxN = 1e4 + 10;
int a[MaxN], b[MaxN];

int main() {
    srand((unsigned)time(NULL));
    for(int i = 0; i < 10000; ++i)
        a[i] = i + 1;
    int index, temp, rest = 10000;
    for(int i = 0; i < 10000; ++i) {
        index = rand() % rest;
        b[i] = a[index];
        temp = a[index];
        a[index] = a[rest - 1];
        a[rest - 1] = temp;
        rest--;
    }
    for(int i = 0; i < 10000; ++i)
        printf("%d  ", b[i]);
    printf("\n");
    return 0;
}

<think>好的,用户问的是C++随机数会有重复的。我得先理解问题。用户可能是在编程时遇到了随机数重复出现的情况,想知道这是否正常,或者是是自己哪里写错了。 首先,C++里的随机数生成其实分为伪随机和真随机。伪随机数生成器(PRNG)是根据种子和算法生成数列的,所以如果是同一个种子,生成的序列会完全一样。比如默认的rand()函数,如果设置种子,每次程序启动都会用相同的默认种子,导致生成随机数序列重复。这时候用户可能会觉得“怎么每次运行结果都一样”,这时候需要解释种子设置的问题。 然后是随机数引擎,比如线性同余法(LCG),这些算法本身就有周期性,虽然周期很长,但理论上在足够多次之后会重复。但实际应用中,如果用户生成的数量远小于周期长度,可能会遇到重复过如果用户的需求是对随机数质量要求高,可能需要更复杂的引擎,比如mt19937。 另外,分布的问题也很重要。比如用户使用均匀分布生成整数,范围较小的话,重复的概率自然更大。比如在110之间生成数,重复的概率肯定比110000大很多。这时候需要解释分布范围对重复概率的影响。 还要考虑用户可能没有正确使用引擎和分布。比如每次调用都重新创建引擎,或者没有正确设置种子,导致生成相同的序列。这时候需要提醒用户应该将引擎作为静态变量或者只初始化一次。 另外,C++11之后的<random>库提供了更好的随机数支持,比如std::mt19937和同的分布函数。用户如果还在用旧的rand()和srand(),可能会遇到更多问题,建议升级到新标准。 总结下来,回答需要分几个方面:伪随机的本质、种子设置、引擎的周期、分布范围、正确使用的方法。同时要给出避免重复的建议,比如正确初始化种子,使用合适的引擎和分布,以及处理小范围时的注意事项。</think>C++中的随机数是否会出现重复,取决于具体实现方式和上下文环境。以下分步骤说明: 1. **伪随机数的本质** C++标准库生成随机数是伪随机数,其本质是数学算法生成的确定性序列。只要初始种子(seed)相同,生成的序列就会完全重复。例如: ```cpp std::mt19937 gen1(123); // 固定种子 std::mt19937 gen2(123); // 相同种子 // gen1和gen2将输出完全相同的随机数序列 ``` 2. **周期性问题** 现代随机数引擎(如`mt19937`)具有极大周期($$2^{19937}-1$$),在周期耗尽前重复。但在实际应用中: - 如果生成数量远小于周期长度,会出现周期性重复 - 如果生成数量接近周期长度,终将出现重复序列 3. **分布范围的影响** 当使用随机数分布时,重复概率与取值范围直接相关: ```cpp std::uniform_int_distribution<int> dist(1, 10); // 10个可能值 // 生成5个数时重复概率:约50% // 生成23个数时重复概率超过99%(生日问题) ``` 4. **常见错误导致重复** - 错误1:每次生成都新建引擎 ```cpp for(int i=0; i<10; i++){ std::mt19937 gen(time(0)); // 时间未变化时种子相同 std::cout << gen() << " "; // 将输出重复值 } ``` - 错误2:未正确设置种子 ```cpp std::default_random_engine gen; // 默认构造使用固定种子 // 每次程序启动生成相同序列 ``` 5. **避免重复的建议** - 正确初始化种子: ```cpp std::random_device rd; std::mt19937 gen(rd()); // 使用真随机数作为种子 ``` - 对于需要唯一性的场景: ```cpp std::set<int> unique_numbers; while(unique_numbers.size() < 1000) { unique_numbers.insert(dist(gen)); } ``` - 高精度需求建议使用`std::random_device`(注意:某些实现可能仍是伪随机) 结论:C++随机数本身可能重复,但通过正确使用随机数引擎、合理设置种子、选择适当分布范围,可以有效控制重复概率。对于需要绝对唯一性的场景,需要额外去重机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值