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

當前位置:首頁 > 單片機 > 程序喵大人

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

隨機數(shù)核心組件

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

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

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

種子(Seed)

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

偽隨機數(shù)引擎

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

隨機數(shù)分布

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

真隨機數(shù)生成器

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

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

std::rand

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

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

缺點:

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

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

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

示例代碼:

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

注意:

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

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

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

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

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

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

  • std::uniform_int_distribution:均勻分布的整數(shù)。
  • std::uniform_real_distribution:均勻分布的浮點數(shù)。
  • std::normal_distribution:正態(tài)分布的浮點數(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; // 均勻分布的浮點數(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)分布的浮點數(shù)(均值 0.0,標準差 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)點:

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

生成隨機字符串

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

示例代碼:

#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;
}

注意事項

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

直接這樣寫有什么問題?

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

原因:

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

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

常見的寫法:

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

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

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

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

std::mt19937vsstd::random_device

std::mt19937

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

std::random_device

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

總結(jié)

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


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