Как сделать рандомное число в c

Обновлено: 06.07.2024

Чтобы получить случайное число в С++ используется функция rand() из модуля . Она генерирует псевдослучайные целые числа в диапазоне от нуля до константы RAND_MAX , значение которой зависит от компилятора (стандартом языка не регламентируется).

В приведенной программе генерируется случайное число, при этом значение затравки задается с помощью функции time , которая возвращает текущее время. Прочитать про нее можно тут: Замерить время работы функции на С++.

Чтобы сгенерировать число в диапазоне от 0 до to , можно использовать деление по модулю:

Генерация в диапазоне от from до to — это тоже самое, что генерация от нуля до to-from , но к результату надо добавить to:

При этом, необходимо, чтобы from был меньше to .

Про функции rand, srand и одинаковые случайные числа

Немного исследуем функцию rand, для этого напишем такой пример:

Сколько бы мы ее не запускали — будем получать одинаковый результат. Но почему? Давайте разбираться вместе. Загляним внутрь одной из возможных реализаций этой функции:

Функция возвращает целые числа (от 0 до 32767). Не вдаваясь в подробности этого кода, полученное случайное число, зависит от стартового числа next , которое, как вы видите, установлено в единицу. Отсюда и следует, что числа всегда получаются одинаковыми. Для того, чтобы избежать этой проблемы, в паре с rand() нужно использовать функцию srand( ). Вот ее внутренности:

Как видите, эта функция изменяет стартовое число next , присваивая ему другую величину, получаемую функцией в качестве аргумента. В принципе, это число можно вводить каждый раз вручную, например, так:

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

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы

Для начала нам надо объявить экземпляр класса генерации рандомных чисел:

rand – имя этого экземпляра.

Мы хотим, чтобы пользователь сам вводил количество нужных ему чисел, поэтому пишем следующее:

Затем создаём цикл for:

Мы вводим новую переменную i, равную нулю и задаём условие – пока i меньше, чем a – число, введённое пользователем, будет выполняться код внутри фигурных скобок. А после каждого выполнения условия к i будет прибавляться единица.

Внутри скобок же у нас выполняется код, который выводит в консоль рандомные числа.

Число 100 в скобках означает, что числа будут генерироваться в пределах от о до 100.

Например, если переделать этот кусочек кода так, как написано ниже, то числа будут генерироваться с пределах от 50 до 1000 и т.д.

Работая с этим сайтом, Вы даете согласие на использование файлов Cookie.

Генератор случайных чисел

  • Random () - инициализирует экземпляр класса Random с помощью начального значения, зависящего от текущего времени. Как известно, время может быть представлено в тиках - 100-наносекундных импульсах, начиная с 1 января 0001 года. И значение времени в тиках представляет собой 64-битное целое число, которое и будет использоваться для инициализации экземпляра генератора случайных чисел.
  • Random ( Int32 ) - инициализирует экземпляр класса Random с помощью указанного начального значения. Такая инициализация генератора случайных чисел может быть удобна на этапе отладки программы, поскольку в этом случае при каждом запуске программы будут генерироваться одни и те же "случайные" числа.
  • Next() - возвращает случайное целое неотрицательное число формата Int32 .
  • Next( Int32 ) - возвращает случайное целое неотрицательное число, которое меньше указанного значения.
  • Next( Int32 min, Int32 max) - возвращает случайное целое число в указанном диапазоне. При этом должно соблюдаться условие min NextBytes( Byte []) - заполняет элементы указанного массива байтов случайными числами.
  • NextDouble() - возвращает случайное число с плавающей запятой, в диапазоне [0,0; 1,0).

using System;
namespace MyProgram
class Program
static void Main( string [] args)
Random rnd = new Random ();
for ( int i = 0; i Console .WriteLine( "" , rnd.Next(-100, 101));
Console .ReadKey();
>
>
>

image articles/522/522_1.jpg

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

using System;
namespace MyProgram
class Program
static void Main( string [] args)
for ( int i = 0; i Random rnd = new Random ();
Console .WriteLine( "" , rnd.Next(-100, 101));
>
Console .ReadKey();
>
>
>

image articles/522/522_2.jpg

Поэтому для генерации случайных чисел в программе необходимо создать единственный экземпляр класса Random . Подробнее об этой проблеме смотрите в видео.

Генерация неповторяющейся последовательности чисел

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

using System;
namespace MyProgram
class Program
static void Main( string [] args)
Random rnd = new Random ();
int [] a = new int [100];
a[0] = rnd.Next(0, 101);
for ( int i = 1; i int num = rnd.Next(0, 101); // генерируем элемент
int j;
// поиск совпадения среди заполненных элементов
for (j = 0; j if (num == a[j])
break ; // совпадение найдено, элемент не подходит
>
if (j == i)
< // совпадение не найдено
a[i] = num; // сохраняем элемент
i++; // переходим к следующему элементу
>
>
for ( int i = 0; i Console .Write( " " , a[i]);
if (i % 10 == 9)
Console .WriteLine();
>
Console .ReadKey();
>
>
>

image articles/522/522_3.jpg

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

using System;
namespace MyProgram
class Program
static void Main( string [] args)
Random rnd = new Random ();
int [] a = new int [100]; // массив элементов
int [] count = new int [100]; // массив количества генераций
a[0] = rnd.Next(0, 101);
int c = 0; // счетчик количества генераций
count[0] = 1; // a[0] генерируется только 1 раз
for ( int i = 1; i int num = rnd.Next(0, 101);
c++; // сгенерировали элемент еще один раз
int j;
for (j = 0; j if (num == a[j])
break ;
>
if (j == i)
a[i] = num; i++;
count[i] = c; c = 0; // сохраняем количество генераций
>
>
// Вывод значений элементов
Console .WriteLine( "Значения элементов" );
for ( int i = 0; i Console .Write( " " , a[i]);
if (i % 10 == 9)
Console .WriteLine();
>
Console .WriteLine();
// Вывод количества генераций
Console .WriteLine( "Количество генераций элементов" );
int sum = 0;
for ( int i = 0; i Console .Write( " " , count[i]);
if (i % 10 == 9)
Console .WriteLine();
>
Console .WriteLine( "Общее количество генераций - " , sum);
Console .ReadKey();
>
>
>

image articles/522/522_4.jpg

Перемешивание значений

Часто возникает задача расставить уже имеющийся набор значений в произвольном порядке. С этой целью также используется генератор случайных чисел. Для решения этой задачи создается массив и заполняется значениями, которые необходимо расставить в произвольном порядке.
После этого генерируется два значения индексов массива случайным образом, и значения элементов с полученными индексами меняются местами. Процедура повторяется не менее N/2 раз, где N - количество элементов массива.

using System;
namespace MyProgram
class Program
static void Main( string [] args)
Random rnd = new Random ();
int [] a = new int [100];
for ( int i = 0; i for ( int i = 0; i int i1 = rnd.Next(0, 100); // первый индекс
int i2 = rnd.Next(0, 100); // второй индекс
// обмен значений элементов с индексами i1 и i2
int temp = a[i1];
a[i1] = a[i2];
a[i2] = temp;
>
Console .WriteLine( "Значения элементов" );
for ( int i = 0; i Console .Write( " " , a[i]);
if (i % 10 == 9)
Console .WriteLine();
>
Console .ReadKey();
>
>
>

image articles/522/522_5.jpg

Перемешивание значений является более эффективным если диапазон значений совпадает с их количеством (или близок к нему), поскольку в этом случае значительно сокращается количество генераций случайных элементов.

Автор: Вставская Елена Владимировна

Чтобы стать хорошим программистом — нужно писать программы. На нашем сайте очень много практических упражнений.

Ты в любой момент сможешь отписаться от рассылки.

Основатель проекта


+ Бесплатно, каждую субботу
+ Создание программ с нуля
+ Решение консольных задач

Видео-уроки


+ 300 практических видеоуроков
+ 400 интерактивных задач
+ Видео-решения и разбор

Миссия

Написал программу в которой пользователь может задать числа А и В.

А - минимальное число.
В - максимальное число.

Т.е. по факту это промежуток чисел,тут же программа должна вывести Х - случайное число из данного промежутка.

Проблема в том, что компиляторы(пробовал на онлайн и CodeBlocks) выдают либо одно и тоже число, либо вообще превышают максимальное число - В .

Я же вводил А = 10,В = 100,получал при каждом повторе - Х = 93,бывало и больше 100. В чём проблема? P.s. оставлю 2 кода



3 ответа 3

С приходом стандарта C++11 появился заголовочный файл , позволяющий явно генерировать случайное число из закрытого интервала, причём с равномерным распределением. Используется для этого шаблонный класс std::uniform_int_distribution.

При этом вы получаете значения в диапазоне [a,b) .

Если надо до b включительно ( [a,b] )-

При каждом программы запуске rand() выдает одну и ту же последовательность случайных чисел. Можете однократно вызвать в начале программы srand(time(0)) - для инициализации ГСЧ значением текущего времени.


Т.е. 'rand()' всегда выдает одну и ту же последовательность случайных чисел. Тогда возникает вопрос,какой командой/функцией можно реализовать ГСЧ?

Еще раз и медленно. rand() выдает последовательность случайных чисел. Какую именно - зависит от начальной инициализации. Чтобы можно было отлаживать программу - при каждом запуске программы будет одна и та же инициализация. Если вы уже все отладили - вызываете один раз srand(time(0)) , это приведет к тому, что при каждом запуске программы будет генерироваться своя последовательность. Так понятно или еще нет?

*/* /me включает зануда-mode */ * стоит помнить, что данный способ обладает рядом ограничений и дефектов. в частности, вообще говоря, он не даёт равномерного распределения чисел на отрезке.

Случайные числа в языке программирования С++ могут быть сгенерированы функцией rand() из стандартной библиотеки С++. Функция rand() генерирует числа в диапазоне от 0 до RAND_MAX . RAND_MAX — это константа, определённая в библиотеке . Для MVS RAND_MAX = 32767, но оно может быть и больше, в зависимости от компилятора. Ниже показана простая программка, использующая генератор случайных чисел rand() :

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

В вашем случае это будет:


Всё ещё ищете ответ? Посмотрите другие вопросы с метками c++ математика случайные-числа или задайте свой вопрос.

Связанные

Похожие

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2022 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2022.1.26.41266

Читайте также: