C++實(shí)現(xiàn)隨機(jī)數(shù)生成的現(xiàn)代化封裝
背景知識(shí)
隨機(jī)數(shù)的生成
C++ 的標(biāo)準(zhǔn)庫提供了一套強(qiáng)大且靈活的隨機(jī)數(shù)工具,主要通過以下幾部分組成:
- 隨機(jī)數(shù)引擎:例如
std::mt19937,生成偽隨機(jī)數(shù)序列。 - 分布:例如
std::uniform_int_distribution,對(duì)隨機(jī)數(shù)進(jìn)行分布轉(zhuǎn)換。 - 隨機(jī)數(shù)種子:用于初始化隨機(jī)數(shù)引擎,保證隨機(jī)性。
類的設(shè)計(jì)原則
在設(shè)計(jì)一個(gè)通用的隨機(jī)工具類時(shí),我們可以封裝常見的隨機(jī)操作,例如:
- 生成指定范圍內(nèi)的整數(shù)或浮點(diǎn)數(shù)。
- 按概率生成布爾值。
- 對(duì)容器進(jìn)行隨機(jī)打亂。
類定義與功能分解
以下是 Random 類的完整定義:
#include <chrono>
#include <iostream>
#include <random>
#include <algorithm>
struct Random {
std::mt19937 rnd;
Random()
: rnd(std::chrono::steady_clock::now().time_since_epoch().count()) {}
void setSeed(unsigned int seed) {
rnd.seed(seed);
}
int operator()(int l, int r) {
return std::uniform_int_distribution(l, r)(rnd);
}
double operator()(double l, double r) {
return std::uniform_real_distribution(l, r)(rnd);
}
bool operator()(double p) {
return std::bernoulli_distribution(p)(rnd);
}
template<typename T>
void operator()(std::vector<T>& vec) {
std::shuffle(vec.begin(), vec.end(), rnd);
}
};
下面,我們逐一拆解并講解其核心部分。
隨機(jī)數(shù)引擎的初始化
Random()
: rnd(std::chrono::steady_clock::now().time_since_epoch().count()) {}
std::mt19937:std::mt19937是一種基于梅森旋轉(zhuǎn)算法的偽隨機(jī)數(shù)生成器,具有較好的性能和隨機(jī)性。其名字來源于生成 19937 位的周期序列。初始化種子:
- 默認(rèn)使用當(dāng)前時(shí)間戳(以納秒為單位)作為種子。
- 時(shí)間戳通過
std::chrono::steady_clock獲取,保證種子不同步。
設(shè)置隨機(jī)數(shù)種子
void setSeed(unsigned int seed) {
rnd.seed(seed);
}
- 種子控制隨機(jī)性:
- 給定相同的種子,隨機(jī)數(shù)生成序列是確定的。
- 這種特性非常適合調(diào)試和可復(fù)現(xiàn)的實(shí)驗(yàn)。
生成隨機(jī)整數(shù)
int operator()(int l, int r) {
return std::uniform_int_distribution(l, r)(rnd);
}
std::uniform_int_distribution:- 用于生成均勻分布的整數(shù)。
- 構(gòu)造函數(shù)參數(shù)為上下界
[l, r]。
調(diào)用方式:
分布對(duì)象dist是一個(gè)可調(diào)用對(duì)象。通過傳入隨機(jī)引擎rnd,即可生成一個(gè)隨機(jī)數(shù)。
示例:
Random random; int number = random(1, 10); // 生成 [1, 10] 范圍內(nèi)的隨機(jī)整數(shù)
生成隨機(jī)浮點(diǎn)數(shù)
double operator()(double l, double r) {
return std::uniform_real_distribution(l, r)(rnd);
}
std::uniform_real_distribution:- 用于生成均勻分布的浮點(diǎn)數(shù)。
- 構(gòu)造函數(shù)參數(shù)為上下界
[l, r),即下界閉、上界開。
示例:
Random random; double value = random(0.0, 1.0); // 生成 [0.0, 1.0) 范圍內(nèi)的隨機(jī)浮點(diǎn)數(shù)
按概率生成布爾值
bool operator()(double p) {
return std::bernoulli_distribution(p)(rnd);
}
std::bernoulli_distribution:- 按照給定的概率
p返回true或false。 - 構(gòu)造函數(shù)參數(shù)
p表示返回true的概率,范圍為[0, 1]。
- 按照給定的概率
示例:
Random random; bool result = random(0.7); // 70% 概率返回 true,30% 概率返回 false
隨機(jī)打亂容器
template<typename T>
void operator()(std::vector<T>& vec) {
std::shuffle(vec.begin(), vec.end(), rnd);
}
std::shuffle:- 對(duì)容器元素進(jìn)行隨機(jī)排列。
- 使用
rnd引擎,確保偽隨機(jī)性。
模板設(shè)計(jì):
允許對(duì)任何std::vector<T>類型的容器進(jìn)行操作。
示例:
Random random;
std::vector<int> vec = {1, 2, 3, 4, 5};
random(vec); // 隨機(jī)打亂 vec
使用場景
隨機(jī)分配任務(wù)
假設(shè)有 10 個(gè)任務(wù)需要隨機(jī)分配給 3 名員工:
Random random;
std::vector<int> tasks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
random(tasks);
for (int i = 0; i < tasks.size(); ++i) {
std::cout << "Task " << tasks[i] << " -> Employee " << random(1, 3) << "\n";
}
模擬拋硬幣
Random random;
int heads = 0, tails = 0;
for (int i = 0; i < 100; ++i) {
if (random(0.5)) {
++heads; // 正面
} else {
++tails; // 反面
}
}
std::cout << "Heads: " << heads << ", Tails: " << tails << "\n";
小結(jié)
通過本文的剖析,我們從以下幾個(gè)方面深入了解了 Random 類的設(shè)計(jì)與實(shí)現(xiàn):
- 使用
std::mt19937隨機(jī)數(shù)引擎生成高質(zhì)量偽隨機(jī)數(shù)。 - 利用 C++ 標(biāo)準(zhǔn)庫中的分布對(duì)象生成特定范圍或分布的隨機(jī)數(shù)。
- 封裝常用隨機(jī)功能,提高代碼的可讀性和復(fù)用性。
到此這篇關(guān)于C++實(shí)現(xiàn)隨機(jī)數(shù)生成的現(xiàn)代化封裝的文章就介紹到這了,更多相關(guān)C++隨機(jī)數(shù)現(xiàn)代化封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之二叉樹詳解
二叉樹(Binary tree)是樹形結(jié)構(gòu)的一個(gè)重要類型。許多實(shí)際問題抽象出來的數(shù)據(jù)結(jié)構(gòu)往往是二叉樹形式。本文將通過示例詳細(xì)講解一下二叉樹,需要的可以參考一下2022-03-03
C++入門教程之內(nèi)聯(lián)函數(shù)與extern?"C"詳解
C++中的內(nèi)聯(lián)函數(shù)與靜態(tài)函數(shù)靜態(tài)函數(shù)靜態(tài)函數(shù)的定義靜態(tài)函數(shù)又稱為內(nèi)部函數(shù),下面這篇文章主要給大家介紹了關(guān)于C++入門教程之內(nèi)聯(lián)函數(shù)與extern?"C"的相關(guān)資料,需要的朋友可以參考下2023-01-01
C語言實(shí)例真題講解數(shù)據(jù)結(jié)構(gòu)中單向環(huán)形鏈表
鏈表可以說是一種最為基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)了,而單向鏈表更是基礎(chǔ)中的基礎(chǔ)。鏈表是由一組元素以特定的順序組合或鏈接在一起的,不同元素之間在邏輯上相鄰,但是在物理上并不一定相鄰。在維護(hù)一組數(shù)據(jù)集合時(shí),就可以使用鏈表,這一點(diǎn)和數(shù)組很相似2022-04-04
C++多態(tài)定義及實(shí)現(xiàn)深度剖析
多態(tài)也是面向?qū)ο蟪绦蛟O(shè)計(jì)的重要特性,它都是配合繼承來使用,多態(tài)可以增加程序設(shè)計(jì)的靈活性,這篇文章主要介紹了C++多態(tài)定義及實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-09-09
C++實(shí)現(xiàn)LeetCode(133.克隆無向圖)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(133.克隆無向圖),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++實(shí)現(xiàn)單鏈表刪除倒數(shù)第k個(gè)節(jié)點(diǎn)的方法
這篇文章主要介紹了C++實(shí)現(xiàn)單鏈表刪除倒數(shù)第k個(gè)節(jié)點(diǎn)的方法,結(jié)合實(shí)例形式分析了C++單鏈表的定義、遍歷及刪除相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)打印到紙張
關(guān)于Qt打印內(nèi)容到紙張,網(wǎng)上的辦法非常多,比如有些直接用painter繪制,逐步控制分頁打印。本文介紹的方法則是將內(nèi)容作為html設(shè)置到文檔對(duì)象,再調(diào)用文檔對(duì)象的print方法傳入QPrinter對(duì)象打印,感興趣的同學(xué)可以了解一下2022-01-01

