2013-09-07 4 views
1

Мне нужно сгенерировать случайное число между 1 и n, где n - без знака int. Если n было int, я бы просто написал 1 + rand()% n. Но, к сожалению, n является неподписанным int. Что ты предлагаешь?генерация случайных чисел в C++

+0

Почему это имеет значение, если 'n' это беззнаковое целочисленное значение? В C++ 11 есть намного лучшие способы генерации случайных чисел. – Mahesh

+1

Попробуйте '1 + rand()% n'. –

+0

Смотреть rand() С учетом вреда: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful – knivil

ответ

11

rand() следует избегать по возможности *. Использование http://en.cppreference.com/w/cpp/numeric/random

#include <random> 
#include <iostream> 


int main() 
{ 
    std::random_device rd; 
    std::mt19937 engine(rd()); 
    std::uniform_int_distribution<unsigned> dist(1, 77); 

    for (int i = 0; i != 5; ++i) 
     std::cout << dist(engine) << '\n'; 
} 

* Потому что он разделяет глобальное состояние, получает часто реализуется в виде линейный конгруэнтный двигателя, который имеет несколько недостатков, и это диапазон часто только 0-2^16. Кроме того,% n, где n не является точным кратным диапазону , не дает равномерного распределения.

Edit: Это может показаться излишним, но технически один хотел бы что-то вроде этого, так как mt19937 нужно немного «разогреть»:

std::mt19937 create_seeded_rng() 
{ 
    std::random_device rd; 
    std::array<std::mt19937::result_type, std::mt19937::state_size> seed_data; 
    std::generate(seed_data.begin(), seed_data.end(), std::ref(rd)); 
    std::seed_seq seq(seed_data.begin(), seed_data.end()); 
    return std::mt19937(seq); 
} 

int main() 
{ 
    std::mt19937 rng = create_seeded_rng(); 
    std::uniform_int_distribution<int> dist(0, 100); 

    for (unsigned i = 0; i != 100; ++i) 
     std::cout << dist(rng) << '\n'; 
} 
+0

Благодарим вас за ответ. Могу я попросить вас еще раз? Моя первоначальная проблема заключалась в том, чтобы написать функцию, которая заполняла массив случайными числами в случайном порядке. Итак, что я сделал, это – Igor

+0

#include #include using namespace std; void GenRandArray (int * _result, unsigned int _maxValue) { \t int i; \t random_device rd; \t mt19937 gen (rd()); \t uniform_int_distribution <> dis1 (0, _maxValue - 1); \t uniform_int_distribution <> dis2 (1, _maxValue); \t для (i = 0; i <_maxValue; i ++) \t \t _result [dis1 (gen)] = dis2 (gen); } void main() { unsigned int n = 5; int * ar = new int [n]; GenRandArray (ar, n); } – Igor

+0

@Igor Почему вы хотите заполнить его в произвольном порядке? Это действительно требование, потому что это не имеет смысла для меня. – cooky451

Смежные вопросы