日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 程序喵大人

開發(fā)過程中,經(jīng)常會(huì)遇到生成隨機(jī)數(shù)的需求,本文會(huì)詳細(xì)介紹C++中生成隨機(jī)數(shù)的方法以及一些注意事項(xiàng)。

隨機(jī)數(shù)核心組件

C++11引入了庫,這個(gè)庫提供了隨機(jī)數(shù)生成工具。

下面是C++中生成隨機(jī)數(shù)的核心組件:

  • 隨機(jī)數(shù)引擎:生成偽隨機(jī)數(shù)的算法。
  • 隨機(jī)數(shù)分布:將隨機(jī)數(shù)引擎生成的數(shù)映射到特定范圍或分布。
  • 真隨機(jī)數(shù)生成器:如std::random_device,用于生成高質(zhì)量的隨機(jī)數(shù)。

種子(Seed)

  • 種子是隨機(jī)數(shù)生成器的初始值。
  • 相同的種子會(huì)生成相同的隨機(jī)數(shù)序列。
  • 常用種子來源:
    • 當(dāng)前時(shí)間:std::time(0)。
    • 真隨機(jī)數(shù)生成器:std::random_device。

偽隨機(jī)數(shù)引擎

  • std::mt19937:基于Mersenne Twister算法,周期長,隨機(jī)性好。
  • std::minstd_rand:線性同余生成器,速度快,但隨機(jī)性較差。
  • std::default_random_engine:默認(rèn)引擎,實(shí)現(xiàn)可能因平臺(tái)而異。

隨機(jī)數(shù)分布

  • 均勻分布:std::uniform_int_distribution、std::uniform_real_distribution。
  • 正態(tài)分布:std::normal_distribution。
  • 伯努利分布:std::bernoulli_distribution。

真隨機(jī)數(shù)生成器

  • std::random_device:依賴于硬件或操作系統(tǒng)提供的隨機(jī)數(shù)源。
  • 適用于生成種子或高安全性場景。

生成隨機(jī)數(shù)的方法

std::rand

std::rand是C標(biāo)準(zhǔn)庫中的隨機(jī)數(shù)生成函數(shù),C++中仍然可以使用,但它的隨機(jī)性較差,且范圍固定。

#include  #include // for std::rand and std::srand #include // for std::time int main() { // 使用當(dāng)前時(shí)間作為種子 std::srand(std::time(0)); // 生成一個(gè)隨機(jī)數(shù) int random_value = std::rand(); std::cout << "Random value: " << random_value << std::endl; // 生成一個(gè)范圍在 [0, 99] 的隨機(jī)數(shù) int random_in_range = std::rand() % 100; std::cout << "Random value in [0, 99]: " << random_in_range << std::endl; return 0;
}

缺點(diǎn):

  • std::rand生成的隨機(jī)數(shù)質(zhì)量較低。
  • 范圍限制需要手動(dòng)調(diào)整(如%操作符)。
  • 種子設(shè)置不夠靈活。

std::random_device真隨機(jī)數(shù)

std::random_device是一個(gè)真隨機(jī)數(shù)生成器,通常用于生成高質(zhì)量的隨機(jī)數(shù)種子。

示例代碼:

#include  #include  int main() { std::random_device rd; // 真隨機(jī)數(shù)生成器 std::cout << "Random value: " << rd() << std::endl; return 0;
}

注意:

  • 在某些平臺(tái)上,std::random_device可能會(huì)退化為偽隨機(jī)數(shù)生成器。
  • 大量每次生成隨機(jī)數(shù)都使用std::random_device,性能較差。
  • 通常用于生成種子,而不是直接用于生成大量隨機(jī)數(shù)。

偽隨機(jī)數(shù)引擎和分布

C++11引入了多種偽隨機(jī)數(shù)引擎和分布,可以生成高質(zhì)量的隨機(jī)數(shù)。

常用隨機(jī)數(shù)引擎:

  • std::default_random_engine:默認(rèn)的隨機(jī)數(shù)引擎。
  • std::mt19937:Mersenne Twister算法,高質(zhì)量隨機(jī)數(shù)引擎。
  • std::minstd_rand:線性同余生成器。

常用隨機(jī)數(shù)分布:

  • std::uniform_int_distribution:均勻分布的整數(shù)。
  • std::uniform_real_distribution:均勻分布的浮點(diǎn)數(shù)。
  • std::normal_distribution:正態(tài)分布的浮點(diǎn)數(shù)。
  • std::bernoulli_distribution:伯努利分布(布爾值)。

示例代碼:

#include  #include  int main() { // 使用 Mersenne Twister 引擎 std::mt19937 rng(std::random_device{}()); // 均勻分布的整數(shù) [1, 100] std::uniform_int_distribution<int> dist(1, 100); int random_int = dist(rng); std::cout << "Random integer in [1, 100]: " << random_int << std::endl; // 均勻分布的浮點(diǎn)數(shù) [0.0, 1.0) std::uniform_real_distribution<double> dist_double(0.0, 1.0); double random_double = dist_double(rng); std::cout << "Random double in [0.0, 1.0): " << random_double << std::endl; // 正態(tài)分布的浮點(diǎn)數(shù)(均值 0.0,標(biāo)準(zhǔn)差 1.0) std::normal_distribution<double> dist_normal(0.0, 1.0); double random_normal = dist_normal(rng); std::cout << "Random normal value: " << random_normal << std::endl; return 0;
}

優(yōu)點(diǎn):

  • 隨機(jī)數(shù)質(zhì)量高。
  • 分布靈活,支持多種分布類型。

生成隨機(jī)字符串

可以使用隨機(jī)數(shù)生成器生成隨機(jī)字符串。

示例代碼:

#include  #include  #include  std::string generate_random_string(size_t length) { const std::string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution<size_t> dist(0, charset.size() - 1); std::string result; for (size_t i = 0; i < length; ++i) {
 result += charset[dist(rng)];
 } return result;
} int main() { std::string random_str = generate_random_string(10); std::cout << "Random string: " << random_str << std::endl; return 0;
}

注意事項(xiàng)

std::mt19937 e{std::random_device{}()};

直接這樣寫有什么問題?

如果你只需要生成一次隨機(jī)數(shù),這樣寫沒問題。但如果你需要多次生成隨機(jī)數(shù),最好避免反復(fù)創(chuàng)建和銷毀std::random_device對象,因?yàn)檫@會(huì)帶來不必要的開銷。

原因:

  • 每次創(chuàng)建std::random_device對象時(shí),都會(huì)初始化一個(gè)新的文件句柄(在類Unix系統(tǒng)上,它通常是對/dev/urandom的封裝),這會(huì)帶來文件系統(tǒng)操作的開銷。(不同操作系統(tǒng)的實(shí)現(xiàn)不同)
  • 每次從std::random_device讀取隨機(jī)數(shù)時(shí),都會(huì)觸發(fā)系統(tǒng)調(diào)用(如read系統(tǒng)調(diào)用),這可能會(huì)影響性能。
  • 在Windows系統(tǒng)上,std::random_device通常是對微軟加密API的封裝,每次創(chuàng)建和銷毀std::random_device對象時(shí),都會(huì)初始化和銷毀加密庫的接口,這也會(huì)帶來額外的開銷。

因此,如果需要頻繁生成隨機(jī)數(shù),這種寫法可能會(huì)導(dǎo)致性能問題。當(dāng)然,如果你的應(yīng)用程序?qū)π阅芤蟛桓?,這種寫法也是可以接受的。

常見的寫法:

在許多示例、網(wǎng)站和文章中,通常會(huì)看到以下寫法:

std::random_device rd; std::mt19937 e{rd()}; // 或者 std::default_random_engine e{rd()}; std::uniform_int_distribution<int> dist{1, 5};

這種寫法的優(yōu)點(diǎn)是:

  • std::random_device只被創(chuàng)建一次,避免了反復(fù)初始化和銷毀的開銷。
  • std::mt19937是一個(gè)偽隨機(jī)數(shù)生成器,它的初始化只需要一個(gè)種子(由std::random_device提供),之后的所有隨機(jī)數(shù)生成都在用戶進(jìn)程中完成,不會(huì)涉及系統(tǒng)調(diào)用。

std::mt19937vsstd::random_device

std::mt19937

  • 偽隨機(jī)數(shù)生成器,基于Mersenne Twister算法。
  • 它是自包含的,完全在用戶進(jìn)程中運(yùn)行,不會(huì)調(diào)用操作系統(tǒng)或其他外部資源。
  • 代碼非常穩(wěn)定,跨平臺(tái)性能一致,在任何平臺(tái)上編譯和運(yùn)行它,都會(huì)得到相似的性能和結(jié)果。

std::random_device

  • 是一個(gè)真隨機(jī)數(shù)生成器,但其實(shí)現(xiàn)是不透明的,我們無法確切知道它的底層實(shí)現(xiàn)是什么,它會(huì)做什么,或者它的效率如何,不同系統(tǒng)實(shí)現(xiàn)不一定相同。
  • 每次從std::random_device讀取隨機(jī)數(shù)時(shí),可能會(huì)觸發(fā)系統(tǒng)調(diào)用,因此其性能(每字節(jié)的周期數(shù))可能遠(yuǎn)低于std::mt19937。
  • 它通常用于生成種子,而不是直接生成大量隨機(jī)數(shù)。
  • 如果你為某些嵌入式設(shè)備或手機(jī)進(jìn)行交叉編譯,它的行為可能更加不可預(yù)測。

總結(jié)

  • 對于簡單的隨機(jī)數(shù)需求,可以使用std::rand。
  • 對于高質(zhì)量的隨機(jī)數(shù),推薦使用std::mt19937引擎和分布,這是一個(gè)高效且可靠的偽隨機(jī)數(shù)生成器,適合在用戶進(jìn)程中生成大量隨機(jī)數(shù)。
  • 對于高安全性場景,可以使用std::random_device生成真隨機(jī)數(shù)。
  • std::random_device的行為因平臺(tái)而異,通常用于生成種子,而不是直接生成大量隨機(jī)數(shù)。
  • 如果需要頻繁生成隨機(jī)數(shù),建議避免反復(fù)創(chuàng)建和銷毀std::random_device對象,而是將其作為種子生成器,只初始化一次。


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
關(guān)閉