Вы можете упростить свой тест уникальности, повторяя текущий набор с циклом, где для всех всех предшествующих значений, которые вы проверяете на уникальность из текущего значения:
// Generate a unique random number
bool unique = false ;
while( !unique )
{
x[j] = rand() % RANGE + 1; // Random 1 to 56
// Test uniqueness from all preceding values in
// the set (x[0] is always unique)
unique = true ;
for( int k = 1; unique && k < j; k++ )
{
unique = x[k] != x[j] ;
}
}
Обратите внимание, что еслиЕсли заданная длина велика, то подход сканирования всех предыдущих значений может быть неоптимальным, но в этом случае кажется разумным и простым.
Поскольку вы (вроде бы) спросили,код может быть дополнительно улучшен с помощью (например, кода, включающего в себя следующее):
- Устранить магические числа
- Инициализация первого члена массива, инициализация всех остальных членов в ноль.
- Инициализировать при создании экземпляра (а не определять и назначать отдельно).
- Создавать экземпляры в максимально узкой области действия - не все в верхней части функции
- Не открывать файлдля типов доступа, которые вы не используете («w», а не «w +»)
- Проверка ошибок функций ввода-вывода
- Не используйте типы stdint без необходимости - арифметические операции frравным образом приводят к неявным приведениям к
int
. Используйте int
, если нет веской причины не избегать неожиданностей. Хорошие причины для использования stdint включают соответствие какому-либо формату файла или протоколу связи или совпадению с шириной регистра в драйвере устройства. Не здесь. - Например, тестируйте и исправляйте ошибки (
rand() % 57 + 1
). - Избегайте повторения - используйте цикл (тест уникальности в данном случае).
- Скажите только что-то полезное вКомментарии. Если код самодокументируется, молчите. Если это не очевидно, объясните - не просто повторяйте то, что кто-либо может видеть из кода (например, «Генерация случайного числа»)
- Не пишите комментарии в настоящее непрерывное время (нет)глаголы). Хорошо, не совсем улучшение, просто что-то меня раздражает ;-). Исходный код описывает то, что программа будет делать, а не то, что делает .
- Не записывать посторонние пробелы после последнего значения в каждой строке.
- Удалите ненужный код - например, цикл в конце обнуляет
x[]
- Если вы обещаете вернуть значение, верните значение.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SET_LENGTH 6 // Number of values in each set
#define SET_COUNT 100 // Number of sets
#define RANGE 56 // Range of each value 1 to RANGE
int main()
{
// Initialing Random Generation C Library
srand(time(NULL));
int x[SET_LENGTH] = {0};
// Open file
FILE* fp = fopen( "combinations.txt", "w" ) ;
if( fp != NULL )
{
// For each random number set...
for( int i = 0; !ferror( fp ) && i < SET_COUNT; i++ )
{
// For each number in the set...
for( int j = 0; j < SET_LENGTH; j++)
{
// Generate a unique random number
bool unique = false ;
while( !unique )
{
x[j] = rand() % RANGE + 1; // Random 1 to 56
// Test uniqueness from all preceding values in
// the set (x[0] is always unique)
unique = true ;
for( int k = 1; unique && k < j; k++ )
{
unique = x[k] != x[j] ;
}
}
// Write value to file.
// Space separated values with newline end.
fprintf(fp, "%d%c",x[j],
j < SET_LENGTH - 1? ' ' : '\n' ) ;
}
}
}
fclose(fp);
return 0 ;
}
Не "улучшено"Здесь возникает проблема «случайного смещения», которая возникает, когда для rand() % n
, n
не является фактором RAND_MAX+1
. Если случайность имеет решающее значение, вы можете рассмотреть это.