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);
  • first 和 last:表示要随机打乱的范围([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. 代码解析

  • 创建随机数生成器

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

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

    • 遍历并输出 vec

4. 示例输出

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

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

5. 重要说明

为什么不用 std::random_shuffle

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

std::mt19937 vs std::default_random_engine

  • std::default_random_engine 可能因不同的编译器实现不同,因此推荐使用 std::mt19937

如何使用固定种子进行可复现的随机洗牌?

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 以获得更好的随机性和可控性!

到此这篇关于C++中std::shuffle的使用小结的文章就介绍到这了,更多相关C++ std::shuffle内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源链接:https://www.jb51.net/program/339169b4k.htm

© 版权声明
THE END
支持一下吧
点赞8 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容