Как заполнить массив случайными числами

от admin

1.10. Заполнение массивов случайными числами

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

cout << «Введите значения для элементов массива:\n»;

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

Функция rand() определена в библиотеке stdlib и умеет генерировать псевдослучайное целое число между 0 и константой RAND_MAX, определённой в той же библиотеке. Перед использованием датчик случайных чисел необходимо инициализировать начальным значением. Для этого предназначена функция srand(unsigned long int), которая получает целый положительный аргумент и задаёт начальное число для функции rand(). Агрумент функции srand() можно вводить c клавиатуры. Тогда при вводе одинаковых значений можно получить одинаковые последовательности случайных чисел, что полезно для отладки программы. При вводе разных значений аргумента функции srand() генерируемые последовательности случайных чисел будут разными. Если вводить с клавиатуры начальное число нежелательно, то можно считывать его с системного таймера, например, так srand(time(NULL)). Функция time() принадлежит библиотеке time. Таким образом, для заполнения массива целыми числами от 0 до N можно использовать фрагмент

srand(time(NULL)); //Инициализируем датчик

for (i=0;i<=99;i++) //Для каждого элемента

x1[i]=rand()%(N+1); //Присваиваем случайное число

Здесь использована операция взятия остатка от деления для приведения диапазона значений случайной величины к отрезку [0;N]. Если необходимо заполнить массив вещественными псевдослучайными числами из отрезка [a; b], можно писать так:

Здесь результат деления rand()/RAND_MAX по смыслу является вещественным случайным числом из отрезка [0; 1]. Однако компилятор C (C++) при делении целого на целое не выполняет приведения типа результата к вещественному числу. Поэтому в выражение введено умножение на вещественную единицу 1:0. Поскольку в правой части выражения встретился хоть один вещественный множитель, результат будет приведён к вещественному типу. Преобразование y = a + (b – a)x позволяет трансформировать диапазон значений x [0,1] в диапазон значений y [a,b].

Заполнить одномерный массив целыми случайными числами в диапазоне от -100 до 100 и определить количество положительных элементов и выдаёт сообщение на экран.

int m[30]; //Описание массива

int i; //параметр цикла for

int n; //счётчик положительных элементов

srand(time(NULL)); //Инициализация датчика

for (i=0; i<=29;i++) //заполнение массива

m[i]=rand()%201-100; //формирование СЧ в диапазоне от -100 до 100

n=0; //обнуление счётчика элементов

if (m[i]>0) //Условие положительности

n++; //Наращиваем на 1 счетчик

cout << “в массиве “ << n << “ положительных элементов”;

Заполнить одномерный массив вещественными случайными числами в диапазоне от -0.0 до 10.0 и определить значение и индекс (номер) максимального элемента этого массива.

float m[30]; //Описание массива

int i; //параметр цикла for

float max; //значение максимального элемента

int t; // индекс (номер) макс. элемента

srand(time(NULL)); //Инициализация датчика

for (i=0; i<=29;i++) //заполнение массива

m[i]=10.0*rand()/RAND_MAX; //формирование СЧ в диапазоне от 0 до 10.0

// допустим, что 1-й элемент максимален

for (i=1; i<=29;i++) //все остальные элементы

if (m[i]>max) //сравниваем с максимальным

cout << «максимальный элемент justify»> cout << «номер максимального элемента » << t;

Задан двумерный массив b[10][10] целых чисел, заполненный случайными числами из отрезка [-10,10]. Найти и вывести на экран те элементы массива, которые больше заданного числа k.

srand(time(NULL)); //Инициализация датчика

for (i=0; i<=9; i++) //заполнение массива

b [i][j]=rand()%21-10; //формирование СЧ в диапазоне от -10 до 10

cout << «Введите число k»;

1.11. Ссылки в С++

Ссылки – особый тип данных, являющийся скрытой формой указателя, который при использовании автоматически разименовывается. Ссылка может быть объявлена как другим именем, так и как псевдоним переменной, на которую ссылается.

// структура объявления ссылок

/*тип*/ &/*имя ссылки*/ = /*имя переменной*/;

При объявлении ссылки перед её именем ставится символ амперсанда «&«, сама же ссылка должна быть проинициализирована именем переменной, на которую она ссылается. Тип данных, на который указывает ссылка, может быть любым, но должен совпадать с объектом, на который ссылается, то есть с типом данных ссылочной переменной. Для удобства, будем называть переменную, на которую ссылается ссылка «ссылочной переменной». Любое изменение значения содержащегося в ссылке повлечёт за собой изменение этого значения в переменной, на которую ссылается ссылка. Разработаем программу, в которой объявим ссылку на объект типа int.

// №1.cpp: определяет точку входа для консольного приложения.

using namespace std;

int main(int argc, char* argv[])

int &reference = value; // объявление и инициализация ссылки значением переменной value

cout << «value justify»> cout << «reference justify»> reference+=15; // изменяем значение переменной value посредством изменения значения в ссылке

cout << «value justify»> cout << «reference justify»> system(«pause»);

В строке 10 объявлена ссылка reference типа int на переменную value. В строке 13 суммируется значение переменной value с числом 15, черезссылку reference. Результат работы программы (рис. 15.1).

Рис. 15.1.Ссылки в С++

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

Ссылки, как правило, в большинстве случаев используют в функциях как ссылки-параметры или ссылки-аргументы. Напомню, что в языке программирования С++ в функции передаются данные по значению и по ссылке. Так вот, когда происходит передача по значению, те данные, которые необходимо передать, нужно сначала скопировать, а когда передаётся большой объём данных, то только на передачу затрачивается большое количество времени и ресурсов. В таком случае необходимо использовать передачу по ссылке, в этом случае данные копировать нет необходимости, так как к ним обеспечен прямой доступ, но нарушают безопасность данных, хранимых в ссылочных переменных, так как открывают прямой доступ к этим данным. Хотя далее мы рассмотрим, как обеспечить целостность данных и скорость их передачи. Для этого, разработаем программу, в которой создадим три функции, аргументы в которых будут передаваться по значению и по ссылке. Вдобавок ко всему этому ещё и передачу через указатель осуществим. Частенько возникает путаница между указателями и ссылками, на первый взгляд и ссылки и указатели работают одинаково, но разница все, же есть и весьма значительная.

// reference.cpp: определяет точку входа для консольного приложения.

using namespace std;

int sum_by_value(int );// суммирование по значению

int sum_by_reference(int &);// суммирование по ссылке

int sum_by_pointer(int *); // суммирование по указателю

int _tmain(int argc, _TCHAR* argv[])

cout << «sum_by_value justify»> cout << «value justify»> cout << «sum_by_reference justify»> cout << «value justify»> cout << «sum_by_pointer justify»> cout << «value justify»> system(«pause»);

int sum_by_value(int value)// функция принимающая аргумент по значению

int sum_by_reference(int &reference) // функция принимающая аргумент по ссылке

int sum_by_pointer(int *ptrvalue)// функция принимающая аргумент через указатель

*ptrvalue += *ptrvalue;// арифметика с указателем

Начальное значение осталось неизменным в случае передачи по значению, тогда как передача по ссылке и через указатель изменили значение передаваемой переменной. Таким образом, нет необходимости использовать глобальные переменные при необходимости изменения значения передаваемой переменной, нужно воспользоваться ссылкой или указателем. В случае использования указателя строка 16 нельзя забывать про операцию взятия адреса, так как аргументом является указатель. В случае со ссылкой, достаточно указать только имя переменной и всё строка 14. Результат работы программы (рис. 15.2).

Рис. 15.2. Ссылки в С++

В чём же разница между указателями и ссылками? Основное назначение указателя – это организация динамических объектов, то есть размер, которых может меняться (увеличиваться или уменьшаться). Тогда как ссылки предназначены для организации прямого доступа к тому, или иному объекту. Главное отличие состоит во внутреннем механизме работы. Указатели ссылаются на участок в памяти, используя его адрес. А ссылки ссылаются на объект, по его имени (тоже своего рода адрес). Если нет необходимости изменить передаваемое значение в ссылочной переменной, но нужно выиграть в скорости, используйте спецификатор const в объявлении параметров функций. Только так и можно защитить данные от случайного их изменения или полной потере.

Читать:
Веб службы hp как подключить

int sum_by_reference(const int &reference) // функция принимающая аргумент по ссылке

// квалификатор const не даёт изменить передаваемый аргумент внутри функции

filling an array with random number

I’m trying to fill an array of 20 ints with numbers from 1-20 in random sequence. here’s my code:

I’ve created a lookup array to check if the random number is not yet chosen and stored it in array. As you can see I’ve created 2 loops, one for traversing array and the while for choosing the random number. In every while loop iteration the number may reappear and causing another while loop. Is there faster way to do this?

10 Answers 10

You could fill the array in sequence and then shuffle it. That would prevent having to ever do more than 20 random number generations.

Properly implemented, the Fisher–Yates shuffle is unbiased, so that every permutation is equally likely. The modern version of the algorithm is also rather efficient, requiring only time proportional to the number of items being shuffled and no additional storage space.

rand() – генератор случайных чисел в C++

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

Не всегда надо заполнять числовые одномерные и двумерные массивы порядковыми номерами или конкретными значениями. Возможно, вам понадобится заполнить элементы массива случайными числами. В С++ для этого есть специальные фyнкции rand() и srand() .

Они находятся в библиoтечном файле cstdlib , поэтому чтобы их применять в программе, необходимо подключить этот библиотечный файл: #include <cstdlib> или #include <stdlib.h> (для старых компиляторов).

Если воспользоваться только функцией rand() – будем получать одинаковые “случайные числа” от запyска к запуску. Наберите следующий код и откомпилируйте программу несколько раз. Обратите внимание, что “случайные числа” всегда будут одинаковы.

Случайное число генерируется в строке 11 и записывается в i -й элемент массива randomDigits . В следующей строке просим его показать. Запуская программу будем видеть каждый раз oдни и тe же числa:

генератор случайных чисел C++, rand c++, srand c++

Получается, что числа генерируются не совсем случайные. Чтобы добиться “настоящей” случайности чисел при повторных запуска x программы, необходимо применить функцию srand() до функции rand() . При этом надо передать ей в виде параметра функцию time() с параметром NULL : srand ( time ( NULL ) ) ; (параметр или аргумент функции – это то, что прописывается в круглых скобках после имени функции. Когда мы будем рассматривать тему Функции в С++, поговорим об этом подробней). Таким образом srand() получает в виде параметра текущее системное время, которое при каждом запускe программы будет разным. Это позволит функции rand() каждый раз генерировать именно случайные числа. Для использования time() необходимо подключить библиотечный файл ctime ( time.h для более старых компиляторов): #include <ctime> .

Пробуйте запускать. Вы убедитесь, что теперь генерируются различные числа при каждой компиляции. У меня получился такой результат:

rand c++, srand c++, генератор случайных чисел

Первая компиляция

rand c++, srand c++, генератор случайных чисел

Вторая компиляция

Все выглядит неплохо. Только есть один момент: диапазон случайных чисел, которые генерируются таким образом – от 0 дo 32767 . Возможно вам понадобится заполнить массив числами от 200 дo 300, от 0.1 дo 1, от -20 дo 20. Такую генерацию случайных чисел возможно и несложно реализовать. В примере рассмотрим несколько случаев:

В первом цикле 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.

rand c++, srand c++, генератор случайных чисел C++

Чтобы попрактиковаться, попробуйте решить задачу: компьютер “загадывает” число oт 1 дo 7, a пользователь должен его отгадать. Если не получится – смотрите наш вариант решения:

Массивы в PascalABC.NET

В PascalABC.NET рекомендуется использовать динамические массивы. В отличие от статических, они имеют огромное количество методов и операций, просты в создании, заполнении и выводе.

Описание и выделение памяти

Динамический массив описывается так:

Память под динамический массив a выделяется в момент работы программы:

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

Можно совместить описание и выделение памяти — тип динамического массива выводится автоматически:

Обычно в PascalABC.NET совмещают описание динамического массива, выделение памяти и заполнение значениями. Самый простой способ — заполнить n нулями:

Индексация в динамических массивах и использование статических массивов

Динамические массивы индексируются с нуля — это эффективно. В качестве индексов в динамических массивах могут выступать только целые.

Статические массивы тем не менее иногда удобно использовать — в задачах, где индексы либо символьные, либо по-существу начинаются не с нуля. Например, для подсчёта количества слов на каждую букву может использоваться стаический массив

Заполнение статических массивов — увы — производится в цикле. Кроме того, они не помнят свою длину и передача таких массивов в качестве параметров подпрограмм связана с техническими сложностями 40-летней давности, не нужными начинающим.

Простейшее заполнение

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

Простейшее заполнение — набором значений:

Заполнение диапазоном целых или символьных значений делается с использованием функции Arr:

Заполнение определённым значением осуществляется с помощью операции умножения массива на число:

Для заполнения можно также использовать функцию ArrFill:

Для заполнения массива случайными значениями следует использовать

Не рекомендуется использовать алгоритм для заполнения массива случайными в каждой задаче:

Повторять этот текст в каждой задаче — странно. Для этого есть стандартные функции.

Ввод и вывод элементов массива

Для ввода элементов массива базовых типов используются функции

Стандартная процедура вывода Write или Print выводит значения в массиве в квадратных скобках черезх запятую:

Однако лучше всего для вывода воспользоваться методом Print, выводящим все значения в массиве через пробел:

Не рекомендуется вводить и выводить элементы массива в цикле

Повторять этот текст в каждой задаче — странно. Для этого есть стандартные функции.

Циклы по массиву

Для обработки элементов массива используются следующие циклы:

    Цикл for по индексам (если требуется менять элементв или нужна информация об индексах)

Похожие статьи