C ++ 11 size birçok yeni seçenek sunar random
. Bu konudaki kanonik yazı C35'te N3551, Rastgele Sayı Üretimi olacaktır.
Neden kullandığınızı görmek için rand()
sorunlu olabileceğini görmek için GoingNative 2013 etkinliği sırasında verilen Stephan T. Lavavej tarafından hazırlanan Zararlı sunum materyali dikkate alın . Slaytlar yorumlarda yer alıyor, ancak burada doğrudan bir bağlantı var .
Ayrıca boost
, rand
eski kod hala desteğini gerektirebileceği için de kullanıyorum .
Aşağıdaki örnek cppreference sitesinden damıtılmıştır ve std :: mersenne_twister_engine engine ve std :: uniform_real_distribution sayıları üretir [0,10)
dışarı yorumladı diğer motorlar ve dağılımları aralık, ( o canlı izlemek ):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
//
// Engines
//
std::mt19937 e2(rd());
//std::knuth_b e2(rd());
//std::default_random_engine e2(rd()) ;
//
// Distribtuions
//
std::uniform_real_distribution<> dist(0, 10);
//std::normal_distribution<> dist(2, 2);
//std::student_t_distribution<> dist(5);
//std::poisson_distribution<> dist(2);
//std::extreme_value_distribution<> dist(0,2);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(e2))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
çıktı aşağıdakine benzer olacaktır:
0 ****
1 ****
2 ****
3 ****
4 *****
5 ****
6 *****
7 ****
8 *****
9 ****
Çıktı, hangi dağıtımı seçtiğinize bağlı olarak değişecektir, bu nedenle std :: normal_distribution ile 2
her ikisini de içeren bir değerle gitmeye karar verirsek ortalama ve STDDEVP örn dist(2, 2)
yerine çıkış buna benzer olacağını ( o canlı izlemek ):
-6
-5
-4
-3
-2 **
-1 ****
0 *******
1 *********
2 *********
3 *******
4 ****
5 **
6
7
8
9
Aşağıda sunulan kodun bazılarının değiştirilmiş bir sürümüdür N3551
( canlı olarak görün ):
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
std::default_random_engine & global_urng( )
{
static std::default_random_engine u{};
return u ;
}
void randomize( )
{
static std::random_device rd{};
global_urng().seed( rd() );
}
int main( )
{
// Manufacture a deck of cards:
using card = int;
std::array<card,52> deck{};
std::iota(deck.begin(), deck.end(), 0);
randomize( ) ;
std::shuffle(deck.begin(), deck.end(), global_urng());
// Display each card in the shuffled deck:
auto suit = []( card c ) { return "SHDC"[c / 13]; };
auto rank = []( card c ) { return "AKQJT98765432"[c % 13]; };
for( card c : deck )
std::cout << ' ' << rank(c) << suit(c);
std::cout << std::endl;
}
Sonuçlar şuna benzer:
5S 5S 9S 4D 6H TH 6D KH 2S QS 9H 8H 3D KC TD 7H 2D KS 3C TC 7D 4C QH QC QD JD AH JC AC KD 9D 5C 2H 4H 9C 8C JH 5D 4S 7C AD 3S 8S TS 2C 8D 3H 6C JS 7S 6S
artırmak
Tabii Boost.Random da her zaman bir seçenek, burada kullanıyorum boost :: random :: uniform_real_distribution kullanıyorum :
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
int main()
{
boost::random::mt19937 gen;
boost::random::uniform_real_distribution<> dist(0, 10);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(gen))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
rand ()
Kullanmanız gerekiyorsa , kayan noktalı rasgele sayılar nasıl oluşturabilirim konusunda bir kılavuz için C SSS bölümünerand()
gidebiliriz., temelde aralıkta bir açık oluşturmak için buna benzer bir örnek verir.[0,1)
:
#include <stdlib.h>
double randZeroToOne()
{
return rand() / (RAND_MAX + 1.);
}
ve aralığından rastgele bir sayı oluşturmak için [M,N)
:
double randMToN(double M, double N)
{
return M + (rand() / ( RAND_MAX / (N-M) ) ) ;
}