You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何基于给定数组生成多个不重复的随机打乱数组?

问题原因分析
  • 核心问题是指针共享错误:你最初的generate_population函数只调用了一次new int[size]申请内存,后续所有std::random_shuffle操作都是修改同一块内存的内容,同时你把同一个指针ptr赋值给了population数组的所有元素,最终所有population[i]都指向同一块内存,自然输出内容完全一致,该问题和随机种子无关。
  • 次要问题是std::random_shuffle本身的缺陷:该函数从C14开始已经被官方弃用,C17正式移除,它的随机数来源实现未定义,部分实现不依赖std::rand,所以你设置std::srand也可能无法生效。另外std::time(0)返回的是秒级时间戳,如果你多次启动程序间隔小于1秒,确实会出现种子相同的问题,但你本次遇到的问题和该特性无关。
方案说明

你修改后的代码使用C11引入的std::shuffle搭配<random>库的随机引擎,是C标准推荐的数组打乱方案,完全适配你的场景,运行结果正确。
关于效率的相关说明:

  • std::shuffle的时间复杂度是O(n),生成size个随机排列的总时间复杂度为O(size²),这是该场景下的理论最低复杂度,你的实现效率已经达标。
  • 可优化点:你当前的代码每次打乱后会把结果复制回ptr作为下一次打乱的基础,如果你需要的是独立的随机排列,可以删掉std::copy(another, another + size, ptr);这行,每次都复制最开始的初始有序数组即可,既可以避免不同排列之间的相关性,还能省一次拷贝操作。
更安全的实现示例

推荐使用std::vector代替裸指针,避免手动管理内存导致的泄漏问题,参考代码如下:

#include <vector>
#include <algorithm>
#include <random>
#include <cstdio>

int main() {
    constexpr int size = 5;
    // 初始有序数组
    const std::vector<int> base = [](){
        std::vector<int> tmp(size);
        for(int i=0; i<size; i++) tmp[i] = i;
        return tmp;
    }();
    // 存储所有打乱后的数组
    std::vector<std::vector<int>> population;
    population.reserve(size);

    std::random_device rd;
    std::default_random_engine dre(rd());
    for(int i=0; i<size; i++) {
        std::vector<int> tmp = base;
        std::shuffle(tmp.begin(), tmp.end(), dre);
        population.push_back(std::move(tmp));
    }

    // 输出结果
    for(int i=0; i<size; i++) {
        printf("%d: ", i);
        for(int j=0; j<size; j++) {
            if(j>0) printf(", ");
            printf("%d", population[i][j]);
        }
        printf("\n");
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者NotALolicon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:21:02