当前位置: 首页 > news >正文

C++中std::shuffle 的使用

std::shuffle 的使用

std::shuffle 是 C++ 标准库中的一个函数,用于对容器中的元素进行随机排列(洗牌)。它的实现基于现代随机数生成器,因此比 std::random_shuffle 更安全和灵活(std::random_shuffle 在 C++14 被弃用,C++17 后被移除)。


1. 语法

#include <algorithm>
#include <random>

std::shuffle(RandomIt first, RandomIt last, URBG&& g);
  • firstlast:表示要随机打乱的范围([first, last))。
  • g:随机数生成器,必须符合 UniformRandomBitGenerator(如 std::mt19937)。
  • 返回值:无(函数会直接修改输入范围的内容)。

2. 使用示例

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>  // 需要包含 <random> 头文件

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 创建随机数生成器
    std::random_device rd;  // 随机设备(硬件熵源)
    std::mt19937 g(rd());   // 梅森旋转算法(常用的随机数引擎)

    // 打乱顺序
    std::shuffle(vec.begin(), vec.end(), g);

    // 输出打乱后的结果
    std::cout << "Shuffled vector: ";
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

3. 代码解析

  1. 创建随机数生成器

    • std::random_device rd;:用于生成种子。
    • std::mt19937 g(rd());:使用梅森旋转算法(Mersenne Twister)作为伪随机数引擎。
  2. 调用 std::shuffle 进行洗牌

    • std::shuffle(vec.begin(), vec.end(), g); 重新打乱 vec 中的元素顺序。
  3. 打印打乱后的数组

    • 遍历并输出 vec

4. 示例输出

Shuffled vector: 3 7 5 9 1 4 2 8 6

(输出的顺序是随机的,每次运行结果可能不同。)


5. 重要说明

  1. 为什么不用 std::random_shuffle

    • std::random_shuffle 需要内部调用 rand(),它的随机性较弱,而且 rand() 不是线程安全的。
    • std::shuffle 允许使用高质量的随机数生成器(如 std::mt19937)。
  2. std::mt19937 vs std::default_random_engine

    • std::default_random_engine 可能因不同的编译器实现不同,因此推荐使用 std::mt19937
  3. 如何使用固定种子进行可复现的随机洗牌?

    std::mt19937 g(42);  // 42 作为固定的随机种子
    std::shuffle(vec.begin(), vec.end(), g);
    

    这样每次运行代码都会得到相同的打乱结果。


6. 适用场景

  • 随机排序数据
  • 生成随机测试用例
  • 洗牌(如扑克牌游戏)
  • 打乱数据以避免排序偏差(如机器学习数据预处理)

7. 结论

std::shuffle 是现代 C++ 中推荐的随机洗牌方法,结合 std::mt19937 可以提供高质量的随机性,适用于各种随机排列的场景。

🚀 推荐使用 std::shuffle 代替 std::random_shuffle,并搭配 std::mt19937 以获得更好的随机性和可控性!

相关文章:

  • MySQL 多列 IN 查询详解:语法、性能与实战技巧
  • 当 Selenium 的 click() /send_keys()等方法失效时:JavaScript 在 UI 自动化测试中的神奇用法
  • 工作记录 2017-02-06
  • gitlab 提交pr
  • 搭建Nginx
  • springboot第三站(1) web开发引入
  • Docker下载,包含Win、Mac
  • The test of the entire book_《Effective Modern C++》notes
  • Spring Boot集成PageHelper:轻松实现数据库分页功能
  • Linux系统之qrencode工具的安装与基本使用
  • 云安全相关博客阅读(四)
  • 使用静态库动态库也要头文件
  • 【Netty】消息分发处理方式
  • Unity shader管道液体流入并流出效果
  • Spring Boot 静态访问配置属性的解决方案
  • EditRocket for Mac v5.0.2 文本编辑器 支持M、Intel芯片
  • 从信息熵上看图像
  • RISCV虚拟化环境搭建
  • windows主机持久化技术
  • 实用插件推荐 -------- 一个可以将任意语言(python、C/C++、go、java等)的程序转换为汇编语言的小插件
  • 中国一重集团有限公司副总经理陆文俊被查
  • 江西暴雨强对流明显,专家:落雨区高度重叠,地质灾害风险高
  • 玉渊谭天丨一艘航母看中国稀土出口管制为何有效
  • 洛杉矶奥组委确认2028年奥运会和残奥会开闭幕式场地
  • 洞天寻隐·学林纪丨玉洞桃源:仇英青绿山水画中的洞天与身体
  • 北约年度报告渲染所谓“中国核威胁”,国防部回应