Еще одно небольшое изменение подхода bag Weather Vane - это не подготовка пакета всех доступных чисел, а просто объявление массива с максимальным числом элементов, равным диапазону принятых чисел, инициализированных всем нулем(например, int arr[75] = {0};
в этом случае).Нет необходимости заполнять массив, вы просто будете увеличивать элемент на 1 каждый раз, когда это число используется при заполнении вашего массива.
Чтобы убедиться, что вы используете только уникальное число, вы проверяете, является ли соответствующий элемент массива нулевым, если это так, используйте это число и увеличивайте его.Если оно не равно нулю, вы знаете, что число было использовано - сгенерируйте другое и попробуйте снова.
Например, с числом целых чисел для массива 25
и максимальным значением любого целого числа75
, вы можете сделать;:
#define NINT 25
#define MAXI 75
...
int arr[NINT],
seen[MAXI] = {0};
...
for (int i = 0; i < NINT; i++) { /* for each needed element */
int tmp = rand() % MAXI + 1; /* generate a random in range */
while (seen[tmp-1]) /* has been seen/used yet? */
tmp = rand() % MAXI + 1; /* if so, generate another */
seen[tmp-1]++; /* incement element */
arr[i] = tmp; /* assign unique value to arr */
}
( примечание: seen
индексы отображаются как tmp-1
для сопоставления с действительными индексами 0-74
, в то время как числа генерируютсядля tmp
будет 1-75
с использованием rand() % MAXI + 1
. Вы можете использовать любой диапазон, необходимый для этого типа отображения. Использование диапазона чисел от 1000001 - 1000075
все равно потребует только 75-элементный массив seen
.)
Чтобы вывести числа, используемые по порядку, вам просто нужно вывести индекс, соответствующий каждому ненулевому элементу массива seen
(+1
для отображения обратно в диапазон значений 1-75
)Например,
for (int i = 0; i < MAXI; i++)
if (seen[i])
printf (" %d", i + 1);
putchar ('\n');
Сложив все это в кратком примере, вы можете сделать:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NINT 25
#define MAXI 75
int main (void) {
int arr[NINT],
seen[MAXI] = {0};
srand (time(NULL));
for (int i = 0; i < NINT; i++) { /* for each needed element */
int tmp = rand() % MAXI + 1; /* generate a random in range */
while (seen[tmp-1]) /* has been seen/used yet? */
tmp = rand() % MAXI + 1; /* if so, generate another */
seen[tmp-1]++; /* incement element */
arr[i] = tmp; /* assign unique value to arr */
}
puts ("array:");
for (int i = 0; i < NINT; i++) {
if (i && i % 5 == 0)
putchar ('\n');
printf (" %2d", arr[i]);
}
puts ("\n\nused:");
for (int i = 0; i < MAXI; i++)
if (seen[i])
printf (" %d", i + 1);
putchar ('\n');
}
( note: очевидно, размер видимого массива будет ограничендо доступного размера стека, так что если ваш диапазон необходимых чиселпревышает объем памяти, доступный для seen
, объявленного с типом автоматического хранения , вам нужно будет сделать seen
массивом с типом выделенного хранилища ).
Пример использования / Вывод
$ ./bin/randarr25-75
array:
1 18 70 26 75
29 31 58 22 9
5 13 3 25 35
40 48 44 57 56
60 50 71 67 43
used:
1 3 5 9 13 18 22 25 26 29 31 35 40 43 44 48 50 56 57 58 60 67 70 71 75
Используете ли вы сумку или массив для отслеживания увиденных чисел, результаты одинаковы.Никто не лучше другого.Добавьте их обоих в свой C-toolbox.