Форум программистов, компьютерный форум CyberForum.ru

Генерация массива целых случайных чисел, которые не повторяются - C (СИ)

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 702, средняя оценка - 4.98
odip
Эксперт C++
 Аватар для odip
7226 / 3288 / 59
Регистрация: 17.06.2009
Сообщений: 14,165
22.07.2009, 19:31     Генерация массива целых случайных чисел, которые не повторяются #1
Случайные числа.
Генерация случайного целого числа в заданном диапазоне.
Генерация массива целых случайных чисел, которые не повторяются.

Функция rand() возвращает псевдослучайное число в интервале от 0 до RAND_MAX.
Но при запуске программы вы всегда будете всегда получать одну и ту же последовательность чисел. Чтобы этого не происходило следует с помощью функции srand() инициализировать генератор случайных чисел с помощью некоторого начального случайного значения.
Например: srand( time( NULL ) ).

Генерация случайного целого числа в заданном диапазоне.

C
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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int gen_random( int range_min, int range_max );
 
/* ================================================================ */
int main( int argc, char *argv[] ) {
    
int range_min, range_max, rand_val;
 
 
srand( time( NULL ) );
 
if ( argc!=1+2 ) {
    fprintf( stderr, "Usage: gen_random range_min range_max\n" ); exit( 1 );
}
 
range_min= atoi( argv[1] );
range_max= atoi( argv[2] );
rand_val= gen_random( range_min, range_max );
 
printf( "random value in range [%d;%d] is %d\n", range_min, range_max, rand_val );
 
return 0;
 
} /* main() */
 
/* ================================================================ */
int gen_random( int range_min, int range_max ) {
 
if ( range_min>range_max ) {
    fprintf( stderr, "gen_random(): Invalid arguments\n" ); exit( 1 );
}
 
return range_min+rand()%(range_max-range_min+1);
    
} /* gen_random() */


Генерация массива целых случайных чисел, которые не повторяются.

C
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
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define MAX_ARR_SIZE    1024
 
void gen_random_uniq( int arr_size, int *parr, int range_min, int range_max );
 
/* ================================================================ */
int main( int argc, char *argv[] ) {
 
int i, arr_size;
int arr[MAX_ARR_SIZE];
int range_min, range_max;
 
 
srand( time( NULL ) );
 
if ( argc!=1+3 ) {
    fprintf( stderr, "Usage: gen_random_uniq arr_size range_min range_max\n" ); exit( 1 );
}
arr_size= atoi( argv[1] );
range_min= atoi( argv[2] );
range_max= atoi( argv[3] );
if ( arr_size<0 || arr_size>MAX_ARR_SIZE ) {
    fprintf( stderr, "Invalid array size\n" ); exit( 1 );
}
gen_random_uniq( arr_size, arr, range_min, range_max );
 
printf( "random unique array: array size is %d, range is [%d;%d]\n",
    arr_size, range_min, range_max
);
for ( i= 0; i<arr_size; i++ ) {
    printf( " %d", arr[i] );
}
printf( "\n" );
 
return 0;
 
} /* main() */
 
/* ================================================================ */
void gen_random_uniq( int arr_size, int *parr, int range_min, int range_max ) {
 
int i, j;
int dup_flag;
int rand_val, range_width= range_max-range_min+1;
 
 
if ( range_width<1 || arr_size<0 || arr_size>range_width ) {
    fprintf( stderr, "gen_random_uniq(): Invalid arguments\n" ); exit( 1 );
}
 
for ( i= 0; i<arr_size; i++ ) {
    for ( ; ; ) {
        rand_val= range_min+rand()%range_width;
        dup_flag= 0;
        for ( j= 0; j<i; j++ ) {
            if ( rand_val == parr[j] ) { dup_flag= 1; break; }
        }
        if ( !dup_flag ) { break; }
    }
    parr[i]= rand_val;
}
    
} /* gen_random_uniq() */


Генерация массива целых случайных чисел, которые не повторяются (быстрый алгоритм).

C
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define MAX_ARR_SIZE    10240
 
void gen_random_uniq2( int arr_size, int *parr, int range_min, int range_max );
 
/* ================================================================ */
int main( int argc, char *argv[] ) {
 
int i, arr_size;
int arr[MAX_ARR_SIZE];
int range_min, range_max;
 
 
srand( time( NULL ) );
 
if ( argc!=1+3 ) {
        fprintf( stderr, "Usage: gen_random_uniq2 arr_size range_min range_max\n" ); exit( 1 );
}
arr_size= atoi( argv[1] );
range_min= atoi( argv[2] );
range_max= atoi( argv[3] );
if ( arr_size<0 || arr_size>MAX_ARR_SIZE ) {
        fprintf( stderr, "Invalid array size\n" ); exit( 1 );
}
gen_random_uniq2( arr_size, arr, range_min, range_max );
 
printf( "random unique array: array size is %d, range is [%d;%d]\n",
        arr_size, range_min, range_max
);
for ( i= 0; i<arr_size; i++ ) {
        printf( " %d", arr[i] );
}
printf( "\n" );
 
return 0;
 
} /* main() */
 
/* ================================================================ */
void gen_random_uniq2( int arr_size, int *parr, int range_min, int range_max ) {
 
int i, arr2_size, index, range_width;
int *parr2= NULL;
 
 
/* Check arguments */
range_width= range_max-range_min+1;
if ( range_width<1 || arr_size<0 || arr_size>range_width ) {
        fprintf( stderr, "gen_random_uniq2(): Invalid arguments\n" ); exit( 1 );
}
if ( arr_size == 0 ) { return; }
 
 
/* Alloc */
parr2= (int*)malloc( range_width*sizeof(int) );
if ( parr2 == NULL ) {
    fprintf( stderr, "gen_random_uniq2(): No enough memory\n" ); exit( 1 ); 
}
 
/* Init */
for ( i= 0; i<range_width; i++ ) {
    parr2[i]= range_min+i;
}
 
/* Loop */
arr2_size= range_width;
for ( i= 0; i<arr_size; i++ ) {
    index= rand()%arr2_size;
    parr[i]= parr2[index];
    arr2_size--;
    parr2[index]= parr2[arr2_size];
}
 
/* Free */
if ( parr2 != NULL ) { free( parr2 ); parr2= NULL; }
 
} /* gen_random_uniq2() */


Если не подходит стандартный rand().

Дополнительная информация.
http://ru.wikipedia.org/wiki/Генерат...лучайных_чисел

Популярный генератор псевдослучайных чисел.
SIMD-oriented Fast Mersenne Twister (SFMT).
SFMT генерирует 128-битные целые псевдослучайные числа в один шаг.
dSFMT напрямую генерирует вещественные (double) псевдослучайные числа.
http://www.math.sci.hiroshima-u.ac.j...FMT/index.html
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.07.2009, 19:31     Генерация массива целых случайных чисел, которые не повторяются
Посмотрите здесь:

C (СИ) Генерация массива случайных чисел
Генерация случайных чисел из заданного диапазона C (СИ)
Найти числа массива, которые повторяются и занести в новый массив C (СИ)
C (СИ) Генерация случайных четных чисел
Вывести элементы массива А, которые повторяются и одновременно есть в массиве В C (СИ)
Упорядочить по неубыванию массив из 10 указателей на целые числа, которые содержат адреса элементов массива целых чисел. C (СИ)
Генерация случайных чисел в двумерном массиве C (СИ)
Генерация случайных чисел в заданном диапазоне C (СИ)
Дан массив целых случайных чисел. Указать индексы всех нечетных чисел C (СИ)
Из одномерного массива А удалить те элементы, которые повторяются в массиве В C (СИ)
Генерация дробных случайных чисел от 0,1 до 0,9 C (СИ)
Генерация неповторяющихся различных случайных чисел - программа зависает C (СИ)

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Monte-Cristo
 Аватар для Monte-Cristo
2807 / 1372 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
26.07.2009, 22:05     Генерация массива целых случайных чисел, которые не повторяются #2
К слову, rand() генерирует машиннозависимую последовательность. То есть, при каждом запуске на конкретной машине (компьютере) у вас будет генерироваться одна и та же последовательность чисел. Поэтому очень часто применяют srand() который позволяет задать последовательность на основе некого числа (ключа). Как правило, для имитации действительно случайных чисел, в качестве ключа srand() задают текущее време системы: srand(time(NULL));
odip
Эксперт C++
 Аватар для odip
7226 / 3288 / 59
Регистрация: 17.06.2009
Сообщений: 14,165
26.07.2009, 22:11  [ТС]     Генерация массива целых случайных чисел, которые не повторяются #3
Даже если использовать srand(), то все равно rand() будет выдавать псевдослучайные числа. Это следует из самого алгоритма работы rand().
Для генерации действительно случайных чисел нужно использовать аппаратные генераторы.
Rififi
 Аватар для Rififi
2332 / 1047 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
04.08.2009, 20:19     Генерация массива целых случайных чисел, которые не повторяются #4
Генерация случайного числа любой длины.
C++
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
#include <windows.h>
#include <bcrypt.h>
 
#pragma comment(lib, "bcrypt.lib")
 
template <typename T>
void Generate(T& v)
{
    BCRYPT_HANDLE hAlgo = NULL;
    BCryptOpenAlgorithmProvider(&hAlgo, BCRYPT_RNG_ALGORITHM, NULL, 0);
    BCryptGenRandom(hAlgo, reinterpret_cast<PUCHAR>(&v), sizeof(v), 0);
    BCryptCloseAlgorithmProvider(hAlgo, 0);
}
 
#pragma pack(push, 1)
struct LargeData
{
    BYTE raw_[100];
};
#pragma pack(pop)
 
int main()
{
    // Генерация случайного GUID'а
    GUID guid;
    memset(&guid, 0, sizeof(guid));
    Generate(guid);
 
    // Генерация случайного числа размером 100 байт
    LargeData data;
    memset(&data, 0, sizeof(data));
    Generate(data);
 
    return (0);
}

Требуется:
- для компиляции - Windows SDK v6 или выше
- для запуска - Windows Vista или выше

Генерация случайных чисел в диапазоне [a.. b] с использованием генератора Mersenne Twister.
C++
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
#include <time.h>
#include <iostream>
#include <boost/random.hpp>
 
template <typename EngineT, typename DistributionType=int>
struct CRandomT
{
    typedef boost::uniform_int<DistributionType> distribution_type;
    typedef typename distribution_type::result_type result_type;
 
    CRandomT(result_type a, result_type b) : 
    gen_(
        EngineT(static_cast<result_type>(time(NULL))),
        distribution_type(a, b)
        )
    {
    };
    result_type operator()()
    {
        return gen_();
    }
    boost::variate_generator<EngineT, distribution_type> gen_;
};
 
int main()
{
    // Генерация случайного числа в диапазоне [1 .. 10]
    typedef CRandomT<boost::mt19937> CRandom;
    CRandom rnd(1, 10);
    for (int i=0; i<10; i++)
        std::cout << rnd() << std::endl;
 
    return (0);
}

Требуется:
- библиотека Boost.Random
odip
Эксперт C++
 Аватар для odip
7226 / 3288 / 59
Регистрация: 17.06.2009
Сообщений: 14,165
05.04.2011, 16:43  [ТС]     Генерация массива целых случайных чисел, которые не повторяются #5
Генерация случайного числа на UNIX/Linux/BSD с помощью /dev/urandom

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
 
int main( void ) {
 
int fd;
long val;
 
fd= open( "/dev/urandom", O_RDONLY );
 
read( fd, &val, sizeof(val) );
printf( "%ld\n", val );
 
return 0;
 
} /* main() */


Отличия между /dev/random и /dev/urandom

/dev/random и /dev/urandom — специальные символьные псевдоустройства в некоторых UNIX-подобных системах, впервые появившиеся в ядре Linux версии 1.3.30. Они предоставляют интерфейс к системному генератору случайных чисел, который выводит шумы из драйверов устройств и других источников в «хаотичный» пул (англ. entropy pool). Генератор также сохраняет необходимое количество битов шума в этом пуле и формирует из него случайные числа.

При чтении данных в устройстве /dev/random создаются только случайные байты, состоящие из битов шума «хаотичного» пула. Устройство /dev/random может быть необходимо пользователям, которые требуют очень высокого коэффициента случайности, например, при создании ключа доступа и т. п. Если «хаотичный» пул опустел, чтение /dev/random блокируется, пока необходимое количество битов в пуле не будет создано.

Чтение данных устройства /dev/urandom возвратит столько байтов, сколько было запрошено. В результате, если в пуле было недостаточно битов, теоретически возможно будет найти уязвимость алгоритма, использующего это устройство. Если это важно, следует использовать /dev/random.

Взято отсюда: http://ru.wikipedia.org/wiki//dev/ra...8_/dev/urandom


Идея добавить /dev/urandom принадлежит gGrn-7DA
Yandex
Объявления
05.04.2011, 16:43     Генерация массива целых случайных чисел, которые не повторяются
Закрытая тема Создать тему
Опции темы

Текущее время: 15:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru