Дабы отвлечься от конкретного применения рассматриваемого далее алгоритма, "упакую" его в функцию. Эта функция получает на вход массив, его размер и максимальное значение, которое может быть сгенерировано и помещено в одну из ячеек массива (как потом станет ясно, реальное "максимальное" значение будет лишь вполовину заданного). Далее полученный массив заполняется поровну случайными положительными и отрицательными числами в случайном порядке.
Этой функции всё равно, что происходит за пределами своих фигурных скобок, и весь "окружающий мир", т.е. программа, в которую она помещена, представляется тёмным лесом. В свою очередь, программа, использующая эту функцию, будет рассматривать её как чёрный ящик, в который можно поместить массив с указанием необходимых параметров, и получить на выходе заполненный массив.
Генерирую случайное число
Для генерации случайных чисел, мне потребуются библиотеки
#include <stdlib.h>
#include <time.h>
Разумным будет задание размера массива N и максимальное значение MAX для генератора случайных чисел с помощью define:
#define N 10
#define MAX 100
Далее нужно запустить генератор случайных чисел с помощью srand() на основе текущего времени, возвращаемого функцией time(). Внутрь функции я поместил цикл while(), и с каждой новой итерацией будет генерироваться случайное число с помощью функции rand() и сохраняться в переменную buf.
Чтобы генерировать числа от 0 до 99, я должен получить остаток от деления результата работы rand() на MAX.
srand(time(0)); // Завожу генератор случайных чисел
buf = rand() % MAX; // Генерирую случайное число
Отлично, но мне нужно, чтобы генератор случайных чисел генерировал и отрицательные числа. В таком случае, нужно вычесть из полученного случайного числа другое число. Например, если мне требуется получить случайные числа в диапазоне от -50 до 49, то я могу сделать следующее:
buf = rand % MAX - (MAX / 2);
Теперь самое интересное. Мне предстоит...
Заполнение массива
Как заполнить массив одинаковым количеством положительных и отрицательных чисел в случайном порядке? Судя по условию поставленной задачи, количество положительных и отрицательных чисел в массиве размером N должно быть равно N / 2.
Отсюда следует, что можно проследить за количеством накиданных в массив положительных и отрицательных чисел. Так же можно предварительно сохранить случайно сгенерированное число в некий буфер, и посмотреть его знак. На основании этого, принимать решение - заносить очередное сгенерированное число в массив, или нет?
Отлично. Завожу два счётчика, один из которых будет считать количество "положенных" в массив отрицательных чисел, другой - положительных. Цикл while() будет выполняться, пока rand() не сгенерирует достаточное количество случайных чисел для заполнения массива.
int array_fill(int *arr, int len, int max) {
int max_h = max / 2;
int len_h = len / 2;
int buf;
int p = 0; // Счётчик положительных чисел
int n = 0; // Счётчик отрицательных чисел
int i = 0;
srand(time(0));
while(i < len) {
buf = rand() % max - max_h;
if((buf < 0) && (n < len_h)) {
arr[i] = buf;
n++;
i++;
}
if((buf >= 0) && (p < len_h)) {
arr[i] = buf;
p++;
i++;
}
}
return 0;
}
Итак, предположим, что "лимит" на отрицательные числа исчерпан (n == len_h). Цикл будет повторяться, пока в buf не окажется положительное число. То же произойдёт, если p == len_h, только в этом случае цикл будет повторяться до появления в buf отрицательного числа. Таким образом, мы получаем массив, заполненный в равном количестве как положительными, так и отрицательными числами. Задача решена.
Пример вызова функции:
array_fill(arr, N, MAX);
P.S. На самом деле, у этой функции есть один недостаток - при нечётном размере массива она зацикливается. Этот недостаток можно преодолеть, добавив в функцию проверку на чётность размера массива. Если проверка даёт положительный результат, то остаётся сгенерировать ещё одно число и записать его в начало (или конец) массива.
Комментариев нет:
Отправить комментарий