C++ random_shuffle随机洗牌 _ 数组乱序打乱算法【实战】

夜枫大大_9497

夜枫大大_9497

2026-04-09

827人浏览

原创

std::random_shuffle在c++17中已被彻底移除,应改用std::shuffle配合std::mt19937等确定性随机引擎,需显式传入随机数生成器对象并注意迭代器范围与种子管理。

c++ random_shuffle随机洗牌 _ 数组乱序打乱算法【实战】

random_shuffle 已被 C++17 移除,别再用了

直接说结论:std::random_shuffle 在 C++17 中已被彻底移除,编译器(如 GCC 9+、Clang 7+)启用 -std=c++17 或更高标准时会报错:error: 'random_shuffle' is not a member of 'std'。它早在 C++11 就被标记为 deprecated,原因是依赖全局随机状态(std::rand),不可预测、不可重现、线程不安全,且无法指定随机数引擎。

用 shuffle + mt19937 替代 random_shuffle

正确做法是用 std::shuffle 配合高质量随机数引擎,最常用的是 std::mt19937。关键点不是“换函数”,而是必须显式传入一个可调用的随机数生成器对象:

  • std::shuffle 第三个参数必须是函数对象(functor)或 lambda,不能是函数指针或裸 std::rand
  • std::mt19937 需要一个种子(seed),推荐用 std::random_device 初始化,避免每次运行序列相同
  • std::array、原生数组、std::vector 都适用,但注意传迭代器范围(begin/end

示例(打乱 int 数组):

#include <algorithm>
#include <array>
#include <random>

std::array<int> arr = {1, 2, 3, 4, 5};
std::random_device rd;
std::mt19937 g(rd());  // 注意:g 是 generator 对象,不是类型
std::shuffle(arr.begin(), arr.end(), g);</int></random></array></algorithm>

原生 C 风格数组怎么 shuffle?别传数组名

int arr[10] 这类原生数组,不能写 std::shuffle(arr, arr+10, g) —— 这语法合法但危险:如果 arr 是函数参数(即退化为指针),sizeof(arr) 就不是 10,arr+10 可能越界。更稳妥的方式是封装成 std::span(C++20)或用 std::begin/std::end

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载
  • C++11/14/17:用 std::shuffle(std::begin(arr), std::end(arr), g),依赖 ADL 正确推导长度
  • 若需兼容旧标准或手动控制,定义 constexpr size_t N = 10;,再用 arr + N
  • 绝对不要在函数内对形参数组用 sizeof 算长度

想复现某次打乱结果?固定 seed 就行

调试或测试时需要可重现的乱序,就把 std::mt19937 的种子写死,比如 std::mt19937 g(42)。这比老式 srand(42); random_shuffle(...) 更可靠,因为 std::shuffle 的算法是确定性的 Fisher–Yates,引擎行为也完全由 seed 决定。

注意:同一个 g 对象只能用一次 shuffle;如果反复 shuffle 同一容器,需重新构造 g 或调用 g.seed(new_seed),否则后续 shuffle 会基于上次剩余状态,结果仍可重现但非预期。

真正容易被忽略的是:std::shuffle 不抛异常,但若传入无效迭代器范围(如 begin > end),行为未定义;而 std::random_device 在某些嵌入式或受限环境可能抛 std::runtime_error,生产环境建议加 try-catch 或 fallback 到时间种子。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

869

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

2320

5

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5099

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2605

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3168

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2225

10

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.15

811

5

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

2025.11.08

325

7

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

2026.01.05

394

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习