Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > (C++) srand(time(0))


Автор: Natalka 7.12.2006, 19:29
Здравствуйте!Может,кто знает,как сделать так,чтобы выведенные генератором случайных чисел числа были выведены только один раз и не повторялись?

Автор: mr.Anderson 7.12.2006, 19:50
пропиши в начале кода randomize(); .

Автор: Dray 7.12.2006, 21:50
Код

srand( (unsigned)time( NULL ) );
rand();

Ведь в заголовке темы почти правильно написано.

Автор: mr.Anderson 7.12.2006, 21:54
Dray, просто в учебниках обычно пишут именно srand( time( 0 ) );. По своему опыту знаю.

Автор: Natalka 7.12.2006, 22:22
randomize() не работает

Я делаю в Visual C++


генерирует случайное число каждый раз в разном порядке,но числа иногда повторяются.

Нужно исключить повторение чисел.

#include "stdafx.h"
#include <ctime>
using namespace std;
void main()
{
    srand(time(0));
    const int n=10;
 int a[n];
 cout<<"Chisla ot 1 Do 10 :"<<endl;
  for (int i=0; i<n; i++)
  {
      a[i]=rand()%10+1;
      cout<<a[i]<<endl;
  }
}



Автор: Невермайнд 7.12.2006, 22:40
А ты пропиши что  если такое число есть то ренд еще раз

Автор: Partizan 8.12.2006, 07:34
можно делать поиск в массиве и если значение повторяется то просто не записывать его....

есть много разных вариантов как можно эту задачу вообще рещить...

Автор: Dov 8.12.2006, 09:40
Код
void main()
{
    srand(time(0));
    const int n = 10;
    int       a[n];
    int       i, j, temp;

    for (i = 0; i < n; i++)
        a[i] = i + 1;

    cout << "Chisla ot 1 Do 10: " << endl;
    for (i = 0; i < n; i++)
    {
        j = rand() % n;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    for (i = 0; i < n; i++)
        cout << a[i] << " ";

    cout<<endl;
}

Автор: Kuvaldis 8.12.2006, 10:54
В одной умной книжке видел следующую мысль:
ситуация, когда повторяются псевдослучайные числа, называется "неопределенная задержка"
Если нужно получить все из диапазона,  то очень возможен неприятный вариант с очень большим количеством повторений (10000 - диапазон, и нужно получить например, или 2 или 4, остальное выбрано)
На сей случай предлагается такое решение. Без кода, идея:
1. заводим отсортированный массив (это недостаток, но все же) чисел диапазона
2. Генерируем число Е на  шаге K
3. Совершаем ПЕРЕСТАНОВКУ элементов массива (Е, К)

Степень "тасованности" массива в таком случае можно ограничивать количеством итераций (шагов)

P.S. Достаточно эффективно я это когда-то использовал при моделировании раздачи карт в игре (они должны быть все разные, и за приемлемое время).Неприятно, когда сидишь 2 минуты и ждешь, когда сдадут предпоследнюю карту smile 

Автор: Kuvaldis 8.12.2006, 11:10
Не, я еще не выздоровел: промахнулся глазом мимо поста Dov  smile 

Автор: Mayk 8.12.2006, 12:31
Цитата(Dov @  8.12.2006,  13:40 Найти цитируемый пост)
    for (i = 0; i < n; i++)
    {
        j = rand() % n;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

[/quote]
можно заменить на std::random_shuffle(a,a+n);
Эффект - тот же, но рандом_шаффл пишеться в одну строчку



Автор: V.A.KeRneL 11.12.2006, 01:34
Цитата(Mayk @ 8.12.2006,  12:31)
std::random_shuffle(a,a+n);

Если бы мог, сделал бы Mayk'у ++ ))
Имхо, это именно то, что надо!
Узнал про ещё один «вкусный» метод C++
Усилилась и без того немалая радость от предвкушения того, что в следущем семестре наконец-то буду учить «Плюс»! smile

Добавлено @ 01:47 
Цитата(Mayk @ 8.12.2006,  12:31)
Эффект - тот же, но рандом_шаффл пишеться в одну строчку

Эффект, может и тот же, но: 
1) во-первых, random_shuffle действительно пишеться в одну строчку; 
2) во-вторых, он, наверняка, быстрее работает, т.к. содержится в стандартной библиотеке, а значит всячески оптимизирован; 
3) ну и в-третьих, так писать вообще плохо: 
Код

j = rand() % n;

Об этом во вех манах написано!..
Надо так: 
Код

j = (int) (((double) n) * rand() / (RAND_MAX + 1.0));


Автор: JackYF 11.12.2006, 16:02
Цитата(V_A_KeRneL @  11.12.2006,  01:34 Найти цитируемый пост)
j = (int) (((double) n) * rand() / (RAND_MAX + 1.0));


Я думаю, что это наверное, правильней, но нужно его куда-нибудь в макрос или инлайн-функцию... Выглядит ужасно.

Добавлено @ 16:04 
И, кстати, работает медленней, что иногда тоже не самый последний фактор.

Автор: vinter 11.12.2006, 16:37
Цитата

3) ну и в-третьих, так писать вообще плохо: 

код C++    
1:    
j = rand() % n;    

Об этом во вех манах написано!..

это написано совершенно нормально и правильно, а вот это
Код

j = (int) (((double) n) * rand() / (RAND_MAX + 1.0));

изврат
к тому же double тут вообще не причем, rand возвращает целое число..

Автор: JackYF 11.12.2006, 17:18
vinter, 
Цитата(vinter @  11.12.2006,  16:37 Найти цитируемый пост)
это написано совершенно нормально и правильно, а вот это


Код

j = rand() % n;  

Будет работать неверно, если n > RAND_MAX.

А так как RAND_MAX на поверку (у меня) оказался не слишком большим (сколько точно - не помню), то некоторый смысл есть.

а double там, наверное, действительно не нужен... да и скобок многовато:
Код

j = n * ( rand() / (RAND_MAX + 1.0) );


Смотрится гораздо лучше.

Автор: vinter 11.12.2006, 17:32
Цитата

Будет работать неверно, если n > RAND_MAX.

да, че то я притупил.. че то в слишком маленьком диапазоне, он генерирует...
тогда лучше делать так
Код

UINT nNext = time(0);
const UINT a =16070093;
const UINT c = 453816693;
const UINT m = 2147483648;
UINT rand()
{
    nNext = (nNext * a + c) % m; 
    return nNext;
}

хотя я думаю, должен быть такой аналог и в языке, т.к rand() слишком стар для новых машин smile

Автор: V.A.KeRneL 16.12.2006, 00:32
Цитата(JackYF @  11.12.2006, 17:18 Найти цитируемый пост)

а double там, наверное, действительно не нужен... да и скобок многовато:
Код

j = n * ( rand() / (RAND_MAX + 1.0) );



Я просто старался привести код максимально близкий к примеру из man'а.
Цитата

"Если Вы желаете получить случайное число в промежутке от 1 до 10, Вы всегда должны использовать старшие биты, например:

    j=1+(int) (10.0*rand()/(RAND_MAX+1.0));

не следует выполнять такое действие:

    j=1+(rand() % 10);

(т.е. использовать младшие биты)."


Вообще, меня мой код 
Код

j = (int) (((double) n) * rand() / (RAND_MAX + 1.0));

вполне устраивает и ничем не смущает; имхо, самое главное -- корректный. 
Скобочек ещё немного: «I love Scheme!» smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)