Генерация (псевдо)случайных чисел

В обучающих алгоритмических задачках довольно часто встречается необходимость генерации случайных целых чисел. Конечно, можно получать их от пользователя, но с заполнением массива случайными числами в количестве 100 штук могут возникнуть проблемы.

На помощь нам приходит функция стандартной библиотеки языка Си (не C++) rand().

int rand (void);

Она генерирует псевдослучайное целое число на интервале значений от 0 до RAND_MAX. Последнее является константой, которая варьируется в зависимости от реализации языка, но в большинстве случаев составляет 32767.
А что если нам нужны случайные числа от 0 до 9? Типичный выход из ситуации – использование операции деления по модулю.

rand() % 10

Если нам нужны числа от 1 (а не от 0) до 9, то можно прибавить единичку…

rand() % 9 + 1

Идея такая: генерируем случайное число от 0 до 8, и после прибавления 1 оно превращается в случайное число от 1 до 9.

И последнее, самое печальное.
К сожалению, функция rand() генерирует псевдослучайные числа, т.е. числа, которые кажутся случайными, но на самом деле являются последовательностью значений, вычисленных по хитрому алгоритму, в качестве параметра принимающему так называемое зерно (seed). Т.е. сгенерированные функцией rand() числа будут зависеть от значения, которое имеет зерно в момент ее вызова. А зерно всегда устанавливается компилятором в значение 1. Иными словами, последовательность чисел будет хоть и псевдослучайной, но всегда одинаковой.
А это не то, что нам надо.

Исправить ситуацию помогает функция srand().

void srand (unsigned int seed);

Она устанавливает зерно равным значению параметра, с которым была вызвана. И последовательность чисел тоже будет другая.

Но проблема осталась. Как сделать случайным зерно, ведь от него все зависит?
Типичный выходит из ситуации – использование функции time().

time_t time (time_t* timer);

Она тоже досталась в наследство от языка Си и, будучи вызвана с нулевым указателем в качестве параметра, возвращает количество секунд, прошедших с 1 января 1970 года. Нет, это не шутка.

Теперь значение этой функции мы можем передать в функцию srand() (при этом выполняется неявное приведение типа), и у нас будет замечательное случайное зерно.
И числа будут замечательные и неповторяющиеся.

Для использования функций rand() и srand() нужно подключить заголовочный файл <cstdlib>, а для использования time() – файл <ctime>.

Вот полноценный пример.

#include<iostream>
#include<cstdlib>
#include<ctime>

using namespace std;

int main()
{
cout << "10 random numbers (1..100): " << endl;
srand(time(NULL));
for(int i=0;i<10;i++) cout << rand() % 100 + 1 << " ";
cin.get();
return 0;
}

Комментарии (29)

Рубрика: Стандартная библиотека, Язык

29 комментариев на «Генерация (псевдо)случайных чисел»

  1. Виктор

    Только, видимо, Вы не указали, что функция rand генерирует целые числа.

  2. Уведомление: Программа распознавания слова. Продолжение. | Блог Виктора Цвиго.

  3. Katerina

    А что такое cin.get();
    Я так делала:
    #include
    #include
    #include
    using namespace std;
    int main () {
    srand (time(0));
    int a, b, c;
    for (int i = 0; i != 10; ++i) {
    a = rand() % 10;
    b = rand() % 10000;
    c = rand();
    cout << "a:" << a << "\tb:" << b << "\tc:" << c << endl;
    }
    return 0;
    }

Добавить комментарий

Fill in your details below or click an icon to log in:

Логотип WordPress.com

You are commenting using your WordPress.com account. Log Out / Изменить )

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s