Не завжди треба заповнювати числовіодномерные і двумерные массивы порядковыми номерами или конкретными значениями. Возможно, вам понадобится заполнить элементы массива случайными числами. В С ++ для цього є спеціальні ф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 дo32767. Возможно вам понадобится заполнить массив числами от 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)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…До) ):
– поганий спосіб: rand() % До
– гарний спосіб: rand() * До / 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 …
– висновок елемента за межами масиву – це груба помилка.
Спасибо