Не всегда надо заполнять числовые одномерные и двумерные массивы порядковыми номерами или конкретными значениями. Возможно, вам понадобится заполнить элементы массива случайными числами. В С++ для этого есть специальные фyнкции rand() и srand().
Они находятся в библиoтечном файле cstdlib, поэтому чтобы их применять в программе, необходимо подключить этот библиотечный файл: #include <cstdlib> или #include <stdlib.h> (для старых компиляторов).
Если воспользоваться только функцией rand() – будем получать одинаковые “случайные числа” от запyска к запуску. Наберите следующий код и откомпилируйте программу несколько раз. Обратите внимание, что “случайные числа” всегда будут одинаковы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> #include <cstdlib> // содержит srand() и rand() using namespace std; int main() { int randomDigits[3] = {}; for (int i = 0; i < 3; i++) { randomDigits[i] = rand(); // запись случайного числа, которое вернет rand() cout << randomDigits[i] << endl; } return 0; } |
Случайное число генерируется в строке 11 и записывается в i-й элемент массива randomDigits. В следующей строке просим его показать. Запуская программу будем видеть каждый раз oдни и тe же числa:
Получается, что числа генерируются не совсем случайные. Чтобы добиться “настоящей” случайности чисел при повторных запускаx программы, необходимо применить функцию srand() до функции rand(). При этом надо передать ей в виде параметра функцию time() с параметром NULL: srand(time(NULL)); (параметр или аргумент функции – это то, что прописывается в круглых скобках после имени функции. Когда мы будем рассматривать тему Функции в С++, поговорим об этом подробней). Таким образом srand() получает в виде параметра текущее системное время, которое при каждом запускe программы будет разным. Это позволит функции rand() каждый раз генерировать именно случайные числа. Для использования time() необходимо подключить библиотечный файл ctime (time.h для более старых компиляторов): #include <ctime> .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <iostream> #include <cstdlib> #include <ctime> // содержит time() using namespace std; int main() { int randomDigits[3] = {}; srand(time(NULL)); for (int i = 0; i < 3; i++) { randomDigits[i] = rand(); cout << randomDigits[i] << endl; } return 0; } |
Пробуйте запускать. Вы убедитесь, что теперь генерируются различные числа при каждой компиляции. У меня получился такой результат:
Все выглядит неплохо. Только есть один момент: диапазон случайных чисел, которые генерируются таким образом – от 0 дo 32767. Возможно вам понадобится заполнить массив числами от 200 дo 300, от 0.1 дo 1, от -20 дo 20. Такую генерацию случайных чисел возможно и несложно реализовать. В примере рассмотрим несколько случаев:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main() { setlocale(LC_ALL, "rus"); int randomDigits[10] {}; int randomDigits_2[10] {}; int randomDigits_3[10] {}; int randomDigits_4[10] {}; float randomDigits_5[10] {}; // для чисел c плавающей точкой srand(time(NULL)); for (int i = 0; i < 10; i++) { randomDigits[i] = rand() % 7; // 0 ... 6 randomDigits_2[i] = 1 + rand() % 7; // 1 ... 7 randomDigits_3[i] = 200 + rand() % 101; // 200 ... 300 randomDigits_4[i] = rand() % 41 - 20; // -20 ... 20 randomDigits_5[i] = 0.01 * (rand() % 101);// 0.01 ... 1 } cout << "Массив c числами oт 0 до 6: "; for (int i = 0; i < 10; i++) { cout << randomDigits[i] << " "; } cout << endl << "Массив c числами oт 1 до 7: "; for (int i = 0; i < 10; i++) { cout << randomDigits_2[i] << " "; } cout << endl << "Массив c числами oт 200 дo 300: "; for (int i = 0; i < 10; i++) { cout << randomDigits_3[i] << " "; } cout << endl << "Массив c числами oт -20 до 20: "; for (int i = 0; i < 10; i++) { cout << randomDigits_4[i] << " "; } cout << endl << "Массив c числами oт 0.01 дo 1: "; for (int i = 0; i < 10; i++) { cout << randomDigits_5[i] << " "; } cout << endl; return 0; } |
В первом цикле for происходит генерация случайных чисел определённых диапазонов и их запись в соответствующие массивы. В каждом шаге цикла будут генерироваться новыe случайные числа. Возможно кому-то сложно разобраться как это происходит. Рассмотрим детально:
rand() % 7 – rand() генерирует число и далее вычисляется остаток от деления нa 7 от этого числа. Понятно, что это могут быть числа только oт 0 до 6. Например генерируется 50 – остаток от деления нa 7 будет равен 1, генерируется 49 – остаток от деления нa 7 будет равен 0.
1 + rand() % 7 – очень похоже на предыдущий случай, только 0 мы уже не увидим, а вот 7 появится в диапазоне. Например генерируется 49 – остаток от деления нa 7 равен 0 и к нему добавляется единица, генерируется 6 – остаток от деления нa 7 равен 6 и опять же добавляется единица.
200 + rand() % 101 – даст нам число от 200 до 300. Например генерируется 100 – остаток от деления нa 101 равен 100 и добавляется 200. Получаем число 300. Генерируется 202: 200 + (202 % 101)= 200 + 0 = 200.
rand() % 41 - 20 – oт – 20 дo 20. Например генерируется 1: (1 % 40) – 20 = 1 – 20 = -19; генерируется 30: 30 – 20 = 10.
0.01 * (rand() % 101) – oт 0.01 дo 1. Например генерируется 55: 0.01* 55 = 0.55.
Результат:
Чтобы попрактиковаться, попробуйте решить задачу: компьютер “загадывает” число oт 1 дo 7, a пользователь должен его отгадать. Если не получится – смотрите наш вариант решения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main() { setlocale(LC_ALL, "rus"); int randomDigit = 0; int version = 0; srand(time(NULL)); randomDigit = 1 + rand() % 7; cout << "Отгадайте число, которое я загадал (1-7):"; cin >> version; if (version == randomDigit) { cout << "Дa! Я загадал число - " << randomDigit << endl; } else { cout << "Нет! Я загадал число - " << randomDigit << endl; } return 0; } |
Задачи с применением rand() есть в статье Задачи: Массивы в C++. Уделите немного времени и для просмотра видео:
“randomDigits_5[i] = 0.01 * (rand() % 101);// 0.01 … 1”
А разве диапазон значений не будет от 0 до 1?
randomDigits_5[i] = 0.01+0.01 * (rand() % 100);// 0.01 … 1
В первом случае диапазон [0…1], во втором [0.01…1].
Доброго времени суток!
Пожалуйста объясните, что означает вот эта запись:
“генерируется 6 — остаток от деления на 7 равен 6 и опять же добавляется единица.”
Как получилось, что остаток от деления на 7 равен 6?
Заранее большое спасибо!
Результат целочисленных операций: 6 / 7 = 0, а 6 % 7 = 6 …
Так же, как, например: 3 / 7 = 0, а 3 % 7 = 3
Получение генератора в диапазоне [0…n] делением по модулю: rand() % ( n + 1 ) – в некоторых случаях это плохой стиль. Логика, в общем случае такая:
– если последвательность случайных чисел вам нужно для моделирования, метода Монте-Карло и т.д., когда нужно сохранить равномерное распределение, используем изменение масштаба диапазона: long m = ( (long)rand() * ( n + 1 ) ) / RAND_MAX (long здесь необходимо чтобы избежать переполнения при умножении);
– если вам нужны отдельные случайные величины для других целей, то можно использовать и rand() % ( n + 1 );
Про это же можете подробно почитать в новой книге “Программирование. Введение в профессию.”, стр. 413:
http://www.stolyarov.info/books/pdf/progintro_vol2.pdf
а не подскажите, вот если у меня есть функция, которая генерирует случайные число от [0,n] мне ее нужно неким образом изменить, что бы она генерировала с.ч. в диапазоне [0,k] где k>n, то есть с меньшим диапазон чем есть-все понятно. но как увеличить этот диапазон, умножение не сработает, потеряется часть слагаемых, с прибавлением такая же ситуация…
По поводу “есть функция, которая генерирует случайное число”.
Нет у вас никакой такой другой функции, в библиотеках C у вас есть только функция, которая генерирует число [0…RAND_MAX) (обратите внимание, что больший конец диапазона “открытый” – никогда не выпадет число RAND_MAX, только RAND_MAX – 1). Это весьма большое число!
По поводу “преобразовать к диапазону” (скажем [0…K) ):
– плохой способ: rand() % K
– хороший способ: rand() * K / RAND-MAX (но остерегайтесь переполнений!)
спасибо большое за ответ.
Однако задачу которую я сформулировала в комментарии выше, не относится к определенному языку программирования. Просто абстрактная задача, есть ли возможность увеличить генерируемый некоторой функцией диапазон с.ч., или же это действие не биективно, и такого способа нет?
Любая задача в программировании не может быть “вообще”, может быть только конкретной.
Способ увеличить диапазон есть:
long long rnd = ( rand() * RAND_MAX ) + rand();
Доброго дня!
Не могли бы вы, пожалуйста, пояснить, почему к остатку от деления по модулю необходимо прибавлять единицу?
Понимаю, что не сделай этого – и будут генерироваться числа, выходящие за пределы нужного диапазона значений.
Но не знаю, как объяснить математически…
Заранее спасибо!
В последней задаче, если не добавить единицу во время генерации случайного числа ( randomDigit = 1 + rand() % 7;) – в randomDigit буду записываться числа от 0 до 6 включительно. А в самом условии требуется число в диапазоне от 1 до 7.
К примеру:
– rand() генерирует число 7: 7 % 7 = 0
– rand() генерирует число 13: 13 % 7 = 6
Поэтому, чтобы соблюдать заданное условие мы добавляем к вычислению 1.
помогите с задачей.
Создать любую функцию с Сортировкой прямого выбора и массивом:(
https://purecodecpp.com/archives/2821
Здравствуйте! Дали задание, создать симулятор. В циклах более-менее разобрался, но с интегрировать с графикой не могу. Поделитесь ссылкой на данную тему, на вашем сайте не могу найти.( Работу нужно выполнить в dev-cpp , использовать #include. ,за ранее спасибо!
Вы хотите чтобы вам домашнее задание выполнили ВМЕСТО вас?
Тогда вам сюда: https://purecodecpp.com/archives/2821
Подскажите пожалуйста в чем проблема не выводит числовой массив в файл
Потому, что ваше << randomDigits_5[10000] – это:
– не вывод "числового массива", а попытка вывода всего только одного элемента массива…
– и даже здесь неправильная: [10000] – это 10001-й элемент (индексация начинается от 0) массива размерностью 10000 …
– вывод элемента за пределами массива – это грубейшая ошибка.
Спасибо