LINUX.ORG.RU

Исключения в rand()

 , ,


0

2

Привет. Такая задача: есть 2 массива. int One[3]{?, ?, ?, ?}, int Two[2]{?, ?, ?}. В них содержатся данные, причем "?" означает любую цифру от 0 до 99. Нужно, чтобы rand() % 99 генерировал число, которое НЕ совпадает с элементами 2х данных массивов.

Как это реализовать более грамотно? Ведь генерировать число каждый раз, пока оно не войдет в промежуток- не самый лучший вариант. Думал создать массив с допустимыми значениями и уже там по индексу генерировать случайное число, но как тогда из массива sum[99]{0,1,2...99} удалить ячейки с числами, которые входят в массивы, что я написал в самом начале?

PS. Это C++, qt


любую цифру от 0 до 99

Так-то цифры это 0..9, остальное — числа.

s3rjke ()

У тебя два массива, в обоих суммарно меньше десяти элементов. Тебе всего-то и нужно, что после генерации пройтись по массивам и проверить совпадения. Вот это:

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

попахивает каким-то лютым извращением, IMHO

XMs ★★★★★ ()

заведи массив, где будут числа без этих, и бери результат оттуда по rand()

anonymous ()
Ответ на: комментарий от anonymous

И вся эта радость будет с во-о-о-о-о-от таким bias'ом.

anonymous ()
Ответ на: комментарий от anonymous

И вся эта радость будет с во-о-о-о-о-от таким bias'ом.

С чего бы это? Наоборот, это если пытаться постфактум обрабатывать «дырки», а тут будет абсолютно честное распределение.

anonymous ()

Да массив отсутствующих нужен, вернее список ренжев (от и до, например не выпадали еще в ренже 11-13 и 78-79), дергаем ранд и берем ближайший ренж:

int x = range_min + (rand() % (range_max - range_min));

т.е. для ренжа 11-13:

int x = 11 + (rand() % (13 - 11));
Не проверял.

deep-purple ★★★★★ ()

Два массива - не принципиальное усложнение. Предлагаю алгоритм:

1) - Генерируем число из диапазона, уменьшенного на количество чисел в массиве исключений.

2) Если сгенерированное число совпало с исключаемым значением, присваиваем выходному результату число из диапазона, пропущенного при первоначальном усечении диапазона значений.

Elyas ★★★★★ ()

У тебя разных чисел мало:

  • Возьми все числа 0..99.
  • Вычеркни те что есть в массивах.
  • Выбирай случайное из них.
AlexVR ★★★★★ ()
Ответ на: комментарий от anonymous

я так и хотел и об этом писал. Как это реализовать то?

Rot1 ()
Ответ на: комментарий от XMs

А если число совпало с числом в массиве, тогда генерировать снова? Есть же варианты производительнее...

Rot1 ()
Ответ на: комментарий от AlexVR

Это понятно было. Вопрос задал, чтобы мне подсказали, как именно это реализовать

Rot1 ()
Ответ на: комментарий от Rot1

Есть, тебе их выше предложили. Это было просто первое, что в голову пришло

XMs ★★★★★ ()
Ответ на: комментарий от deep-purple

Значения в массивах каждый раз разные. Может быть, например, 23 33 43.

Rot1 ()
Ответ на: комментарий от Rot1

я так и хотел и об этом писал. Как это реализовать то?

Как-то так:

int  a[N];
int* p = a;

for( int i = 0 ; i < N ; ++i ) {
    if( тут проверяй - надо ли добавлять )
        *p++ = i;
}

int count = p - a;
anonymous ()
Ответ на: комментарий от XMs

Пример, почему это не сработает. 99-7=92. В массиве исключений есть число 97 и 55. Зарандомилось число 55. Меняем его на диапазон от 92 до 99, получаем 97. Но оно есть в массиве исключений.

Rot1 ()

int One[3]{?, ?, ?, ?}, int Two[2]{?, ?, ?}

Что с размерностью у вас?

andreyu ★★★★★ ()
Ответ на: комментарий от Rot1

Вопрос задал, чтобы мне подсказали, как именно это реализовать

Задача элементарная. Если ты не можешь её решить и при этом даже не можешь сформулировать, в чём конкретно загвоздка, тебе в программировании делать нечего.

Esper ()
Ответ на: комментарий от Esper

На форуме тебе делать нечего с такими ответами

Rot1 ()
Ответ на: комментарий от Rot1

Ну да, не вполне корректный вариант, но основная идея - генерировать случайное в диапазоне количества допустимых значений, а потом арифметикой приводить к диапазону допустимых. Кратко полный вариант: отсортировать список исключений, исходный rand() если меньше минимального исключаемого - на выход, иначе увеличиваем на единицу и сравниваем со вторым исключаемым и т.д.

Elyas ★★★★★ ()
Ответ на: комментарий от Rot1

Но оно есть в массиве исключений

Проверяем повторно. Тебе в любом случае надо каждый раз по этому массиву проходить, чтобы исключения не получить

XMs ★★★★★ ()
Ответ на: комментарий от Rot1

То, что размер массива на единицу меньше числа указанных элементов

XMs ★★★★★ ()
Ответ на: комментарий от Rot1

а что не так?

$ cat t.cpp
void foo()
{
    int a[3]{1, 2, 3, 4};
}

$ g++ -std=c++11 t.cpp
t.cpp:3:23: error: excess elements in array initializer
    int a[3]{1, 2, 3, 4};
andreyu ★★★★★ ()
Ответ на: комментарий от Rot1

На форуме тебе делать нечего с такими ответами

Какие вопросы, такие и ответы.

Esper ()
Ответ на: комментарий от anonymous

Что это? Указатель на массив? Тогда разыменование дает первый его первый элемент? Можно поподробней?

Rot1 ()
Ответ на: комментарий от Rot1

А если число совпало с числом в массиве, тогда генерировать снова? Есть же варианты производительнее...

И сколько раз в секунду будет вызываться эта функция?

tnodir ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.