Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Random в C (Си)

Ответить
Настройки темы
C/C++ - Random в C (Си)

Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Изменения
Автор: ganselo
Дата: 13-11-2008
Дан массив:
int *x;
x=new int[n];

Я его заполняю рандомно:
Код: Выделить весь код
srand(time(NULL));
for (int i=0; i<n; i++)
x[i]=rand()%100;
Как исключить вероятность того, чтобы значение элементов не могли повториться(т.е чтобы элементы были уникальны)??
Я пробовал так:
Код: Выделить весь код
for (int i=0; i<n; i++)
{
     x[i]=rand()%100;
     for (int j=0; j<n; j++)
     {
           if (i!=j)
           {
               if (x[i]==x[j]) x[i]=rand()%100;
            }
       }
}
Но тут после того как программа нашла схожий элемент и заменила с помощью рэнтома, есть вероятность что этот заменённый элемент может быть не уникальным, по отношению к предыдущим.
Как добится того, чтобы элементы массива были уникальны и при этом время выполнения было как можно минимально.

Отправлено: 19:30, 13-11-2008

 

Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Решил проблему так:

Код: Выделить весь код
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void proverka(int *x, int key);
void size(int *dig);
int n;
int main()
{
    int *x, p=1;
    size(&n);
    x=new int[n];
    srand(time(NULL));
    for (int i=0; i<n; i++)
    {
        x[i]=rand()%100;
        proverka(x, i);

    }
    for (int i=0; i<n; i++)
    {
        printf ("x[%i]=%i\n", i, x[i]);
    }
    printf ("\n");

    for (int i=0; i<n; i++)
    {
        for (int j=0; j<n; j++)
        {
            if (i!=j)
            if (x[i]==x[j]) printf ("xI[%i]=%i, xJ[%i]=%i\n", i, x[i], j, x[j]);
        }
    }
    delete [] x;
}


void proverka(int *x, int key)
{
    for (int i=0; i<key; i++)
    {
        if (x[key]==x[i])
        {
            x[key]=rand()%100;
            proverka(x, key);
        }
    }
}

void size(int *dig)
{
    scanf("%i", &*dig);
}
Но думаю это не лучший вариант, т.к при проверки происходит очень много действий.

-------
К величайшему сожалению "история учит нас тому, что она ничему не учит".


Отправлено: 20:05, 13-11-2008 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


А если использовать цикл do\while? Тоесть пока не будет соблюдено условие (все элементы не проверены) или один из них равен сгернерированному раньше, продолжать генерацию чисел до тех пор пока не будет найденно число, которого нет в массиве.
Код: Выделить весь код
do{
... // код
}while(Условие)

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 20:49, 13-11-2008 | #3


Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Цитата Drongo:
А если использовать цикл do\while? »
спс попробую.

-------
К величайшему сожалению "история учит нас тому, что она ничему не учит".


Отправлено: 20:59, 13-11-2008 | #4

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


я советую алгоритм хитрее: Сгенерировать последовательность чисел, которые должны быть, а потом перемешать их в случайном порядке. Перемешивание делать выбором случайного индекса из последовательности и удалять из списка число, соответсвующее индексу. Либо перетусовать их любым другим способом.
Код: Выделить весь код
int values[200];
for(unsigned n=0; n<200; ++n) values[n] = n;

for(unsigned n=200; 1<n;)
{
   int& rand_idx(values[rand() % n]);
   printf("%i", rand_idx);
   rand_idx = values[--n];
}

printf("%i", values[0]);
такие точно не повторятся
Это сообщение посчитали полезным следующие участники:

Отправлено: 23:47, 13-11-2008 | #5


Новый участник


Сообщения: 49
Благодарности: 17

Профиль | Отправить PM | Цитировать


pva, Вот вывод твоего кода:
1134459160191733723168103531901711854108105291224071587942115869261551291771481125010676133331255147 1531215789147186529713019216191341595894612145856519411114511715181997231273188110146139123391691821 0414229026931326678845613671474189223212418415195131128127551701018517568916410117917313725165176196 1201408218062957012610719336301501521987582019787014696316311618399968316611412128171888149172463515 115410264981621491311960135576713819178241877710980111003848431741671411431615614413418141
Повторяющиеся числа есть, а если нету, то не понятно почему.
Цитата pva:
int& rand_idx(values[rand() % n]);
printf("%i", rand_idx);
rand_idx = values[--n];
»
Поясни пожалуйста, в чем суть этих строчек кода?

P.S Еще вариант
Код: Выделить весь код
1:     #include<conio.h>
2:     #include<stdio.h>
3:     #include<stdlib.h>
4:     #include<time.h>
5:     #include<mem.h>
6:     
7:     
8:     
9:     int main()
10:     {
11:     srand(time(NULL));
12:    
13:     int values[ 200 ], rand_idx=0;
14:     memset( &values, (-1), sizeof(values) );
15:    
16:    
17:     for(unsigned n=0; n<200; )
18:      {
19:      rand_idx = rand() % 200;
20:      if( values[ rand_idx ]==-1 )   values[ rand_idx ] = n++;
21:      }
22:    
23:     for(unsigned n=0; n<200; n++ )
24:      {
25:      printf( "%d ", values[ n ] );
26:      }
27:     return 0;
28:     }

Последний раз редактировалось ___oj, 14-11-2008 в 06:06.

Это сообщение посчитали полезным следующие участники:

Отправлено: 04:57, 14-11-2008 | #6


Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Цитата pva:
я советую алгоритм хитрее: »
Цитата ___oj:
P.S Еще вариант »
Всё хорошо, но тут интервал чисел в массиве будит зависить от размерности массива
(т.е если size=10, то значения x[0], x[1]...x[size] будит пренадлежать интервалу [0, size]). В случае если мне понадобится массив из 10 элементов со зна4ениями на интервале [100, 200] этот вариант я так понимаю не подойдёт?

-------
К величайшему сожалению "история учит нас тому, что она ничему не учит".


Отправлено: 12:47, 14-11-2008 | #7


Ветеран


Сообщения: 3806
Благодарности: 824

Профиль | Отправить PM | Цитировать


Надо создать два алгоритма:
для случая когда размерность массива и интервала допустимых значений примерно равны - перетасовать массив
и когда интервал допустимых значений гораздо больше размерности массива - просто рандомно заполнять, проверяя - нет ли уже таких значений в массиве.
Чтобы проверка работала быстрее - создать два массива - один итоговый, второй - своеобразный индекс - где полученные рандомные значения хранятся в порядке возрастания. Т.к. поис по упорядоченному множеству проходит гораздо быстрее.

Отправлено: 14:08, 14-11-2008 | #8


Новый участник


Сообщения: 49
Благодарности: 17

Профиль | Отправить PM | Цитировать


Цитата ganselo:
о тут интервал чисел в массиве будит зависить от размерности массива »
Ни в коем случае.

Сорри, будит зависеть.

Последний раз редактировалось ___oj, 14-11-2008 в 14:28.


Отправлено: 14:09, 14-11-2008 | #9


Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Цитата ___oj:
Ни в коем случае. »
Пусть размерность массива равна 20,
а масштаб рандомизации я выбрал 200 (т.е рандом будит возврощать значения от 0 до 200 (0<=rand<=200))

Код: Выделить весь код
for(unsigned n=0; n<50; )
    {
        rand_idx = rand() % 200; 
        if( values[ rand_idx ]==-1 )   values[ rand_idx ] = n++;
}
В случае когда мы выбираем слу4айно индекс массива на интервале [0, 200] (rand_idx = rand() % 200; ) и этот индекс больше размерности массива
то мы начинаем проверять с несуществующем элементом массива if( values[ rand_idx ]==-1 ) values[ rand_idx ] = n++;, т.е тут n не увеличится на еденицу.
И следовательно n будит увеличиватся только тогда, когда rand выберит число находящееся на интервале [0, до размерности массива].
Следовательно n увеличится ровно столько раз сколько будит равна размерность массива. И поэтому значение элементов массива не будит превосхадить размерности массива.

-------
К величайшему сожалению "история учит нас тому, что она ничему не учит".


Отправлено: 14:40, 14-11-2008 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Random в C (Си)

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
C/C++ - [решено] Random element deleting HD295 Программирование и базы данных 2 19-05-2009 19:35
Delphi - прога с использованьем "Random" ShadowMas Программирование и базы данных 2 21-11-2008 21:19




 
Переход