【C++实用工具】RandEmmet:致敬Emmet的极简随机数生成器(附完整源码+GitHub)

【C++实用工具】RandEmmet:致敬Emmet的极简随机数生成器(附完整源码+GitHub)

文章目录

在C++开发中,生成随机数是高频需求,但原生 <random>库的用法繁琐、代码冗余,每次都要手动初始化引擎、设置分布、循环生成... 有没有一种像前端Emmet一样极简的方式?

今天给大家分享我封装的RandEmmet工具------一行RandEmmet(10,100)[20]就能生成指定范围、指定数量的随机数,语法简洁到极致,还兼顾性能和健壮性!

一、RandEmmet核心优势

对比原生C++随机数写法,RandEmmet的优势一目了然:

特性 原生<random> RandEmmet工具
语法复杂度 需要手动初始化引擎、分布器,循环生成 一行RandEmmet(min,max)[count]搞定
容错性 范围颠倒(如100,10)需手动校验 自动修正范围,无需额外处理
性能 需手动预分配内存,否则频繁扩容 内置vector预分配,性能拉满
随机质量 易因种子单一导致随机数重复 硬件随机数+时间戳生成高质量种子
健壮性 无参数校验,非法输入易崩溃 内置异常处理,杜绝非法参数

二、快速上手:3行代码用起来

1. 环境要求

  • C++11及以上编译器(支持<random>/<chrono>等库)
  • 无需额外依赖,直接引入头文件即可

2. 基础使用示例

cpp 复制代码
#include <iostream>
#include "RandEmmet.h"

int main() {
    try {
        // 核心语法:RandEmmet(最小值, 最大值)[生成数量]
        auto nums = RandEmmet(10, 100)[20];
        
        // 遍历输出20个10-100的随机数
        for (int num : nums) {
            std::cout << num << " ";
        }
    } catch (const std::exception& e) {
        std::cerr << "错误:" << e.what() << std::endl;
    }
    return 0;
}

3. 运行效果

复制代码
生成的20个随机数:27 16 57 86 88 43 12 34 54 39 39 35 62 89 35 44 78 38 60 13

4. 高级玩法:嵌套生成随机范围

先用RandEmmet生成随机范围,再基于该范围生成随机数,模拟真实业务场景:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include "RandEmmet.h"

// 封装:随机生成范围 → 生成该范围内的随机数
auto RandomWithRandomRange(int base_min, int base_max, int count) {
    auto range = RandEmmet(base_min, base_max)[2];
    int new_min = std::min(range[0], range[1]);
    int new_max = std::max(range[0], range[1]);
    
    std::cout << "随机生成的范围:[" << new_min << ", " << new_max << "]" << std::endl;
    return RandEmmet(new_min, new_max)[count];
}

int main() {
    // 生成3组「随机范围+随机数值」
    for (int i = 0; i < 3; i++) {
        std::cout << "第" << i+1 << "组:" << std::endl;
        auto res = RandomWithRandomRange(10, 100, 8);
        for (int num : res) std::cout << num << " ";
        std::cout << "\n";
    }
    return 0;
}

运行效果:

复制代码
第1组:
随机生成的范围:[59, 87]
85 66 81 85 60 86 64 85 
第2组:
随机生成的范围:[13, 63]
50 17 27 15 38 16 27 16 
第3组:
随机生成的范围:[65, 98]
66 95 88 84 71 85 94 83 

三、核心源码解析:极简语法的底层实现

RandEmmet的核心是类封装+运算符重载,以下是完整源码及关键解析:

完整头文件代码(RandEmmet.h)

cpp 复制代码
#ifndef RANDEMMET_H
#define RANDEMMET_H

#include <vector>
#include <random>
#include <chrono>
#include <algorithm>
#include <stdexcept>

class RandEmmet
{
    int _min;
    int _max;
    std::mt19937 rng; // 梅森旋转算法引擎

    // 懒加载初始化随机数引擎(线程安全+高性能)
    std::mt19937& get_rng() {
        if (rng == std::mt19937{}) {
            std::random_device rd;
            auto seed = rd() + std::chrono::steady_clock::now().time_since_epoch().count();
            rng.seed(seed);
        }
        return rng;
    }

public:
    // 构造函数:初始化范围+自动修正颠倒的min/max
    RandEmmet(int min, int max) : _min(min), _max(max)
    {
        if (_min > _max) {
            std::swap(_min, _max);
        }
        get_rng(); // 提前初始化引擎
    }

    ~RandEmmet() = default;

    // 核心:重载[]运算符,实现极简语法
    std::vector<int> operator[](int count)
    {
        if (count < 0) {
            throw std::invalid_argument("生成随机数的数量不能为负数!");
        }

        std::vector<int> res;
        res.reserve(count); // 预分配内存,避免频繁扩容
        std::uniform_int_distribution<int> dist(_min, _max);
        auto& rng = get_rng();

        for (int i = 0; i < count; i++) {
            res.push_back(dist(rng));
        }
        return res;
    }
};

#endif

关键实现细节

  1. 懒加载引擎初始化get_rng()方法仅在首次使用时初始化引擎,避免空构造的无用开销,同时组合std::random_device(硬件随机数)+ 时间戳生成种子,杜绝随机数重复;
  2. 构造函数容错 :自动交换颠倒的min/max,比如RandEmmet(100,10)会自动修正为10-100
  3. []运算符重载 :这是极简语法的核心!RandEmmet(10,100)[20]中,(10,100)调用构造函数,[20]调用重载的operator[],直接返回生成好的vector;
  4. 性能优化reserve(count)预分配内存,避免vector循环中频繁扩容,生成大量随机数时性能提升显著;
  5. 异常处理 :校验count是否为负数,抛出明确的异常信息,提升代码健壮性。

四、编译&运行

1. 编译命令

bash 复制代码
# g++编译(需指定C++11)
g++ main.cpp -o RandEmmet -std=c++11

# 运行程序
./RandEmmet

2. 兼容性

  • Windows:支持MSVC、MinGW编译器;
  • Linux/Mac:支持g++、clang++编译器;
  • 所有环境仅需C++11及以上版本。

五、开源地址

完整源码、示例代码已上传GitHub,可直接克隆使用:

👉 GitHub地址:https://github.com/dxiangwiki/RandEmmet

六、扩展方向(可自行迭代)

  1. 支持浮点数生成:新增RandEmmet(double min, double max)重载构造函数+operator[]
  2. 线程安全版本:封装std::mutex保证多线程下引擎安全;
  3. 自定义随机分布:支持正态分布、泊松分布等;
  4. 静态方法封装:新增RandEmmet::randInt(min, max, count)静态方法,适配不同使用习惯。

总结

RandEmmet的设计核心是「极简+实用」:把C++原生随机数库的复杂逻辑封装成贴近自然语言的语法,让开发者聚焦「生成什么随机数」,而非「怎么生成随机数」。

无论是快速生成测试数据、模拟真实业务场景,还是学习C++类封装/运算符重载,这个工具都能满足需求。欢迎Star、Fork、提Issue,一起完善这个小工具~


文章发布小贴士(适配CSDN)

  1. 发布时选择「原创」,分类选「C/C++」→「C++编程」;
  2. 插入运行效果截图(比如生成随机数的终端输出),提升可读性;
  3. 标签添加:C++随机数EmmetC++11封装GitHub
  4. 文末可添加「点赞+收藏+关注」引导,提升文章曝光。
相关推荐
木易 士心1 小时前
Java中 synchronized 和 volatile 详解
java·开发语言·jvm
智者知已应修善业1 小时前
【花费最少钱加油到最后(样例数据推敲)】2024-11-18
c语言·c++·经验分享·笔记·算法
三无少女指南1 小时前
我把 oh-my-openagent 翻了一遍,终于看懂它为什么不像一个插件,而像一套多 Agent 编排系统
开发语言·ai
mjhcsp2 小时前
C++状压 DP解析
开发语言·c++·动态规划·状压 dp
Roc.Chang2 小时前
Rust 入门 - RustRover 新建项目时四种项目模板对比
开发语言·后端·rust
故事和你912 小时前
sdut-程序设计基础Ⅰ-实验三while循环(1-10)
开发语言·数据结构·c++·算法·类和对象
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:数据结构-并查集
c语言·数据结构·c++·算法
Andy2 小时前
Cpp语法1
c++·c
前端小D2 小时前
面向对象编程
开发语言·javascript