Функция random()
- Войдите на сайт для отправки комментариев
Вс, 10/06/2018 - 21:04
Уважаемые программисты!
При помощи random() генерирую числа от 1 до 10 и записываю их в массив. Подскажите, как избегать повторов в генерации случайных чисел?
Например, сгенерировалось число 1 и записалось в num[0]. Далее нужно, чтобы генерировались числа от 2 до 10 и тд далее, пока все ячейки массива не будут заполнены разными числами.
1. Заполняете массив последовательными числами, например, a[i] = i+1;
2. Пробегаетесь циклом по массиву, меняя текущий элемент со случайным местами. swap(a[i], a[random(N)]);
Можно поконкретнее про оператор swap ? Компилятор не распознает его.
Это более или менее общепринятое название для функции, которая меняет между собой местами два переданных ей параметра.
Ну, примерно так:
Мона ещё и так, без промежуточной переменной:
Разобрался, спасибо.
Буду пытаться интегрировать в код.
Это более или менее общепринятое название для функции, которая меняет между собой местами два переданных ей параметра.
Ну, примерно так:
При компиляции выводит ошибку "too few arguments to function 'void swap(byte&, byte&)". Что я делаю не так ?
На строке 11 не смущает ничего?
При компиляции выводит ошибку "too few arguments to function 'void swap(byte&, byte&)". Что я делаю не так ?
Исправил, но значения a и b между собой не меняются.
https://learnc.info/c/functions.html -> передача аргументов.
Исправил, но значения a и b между собой не меняются.
А с какой стати они должны меняться?
издеваетесь над человеком )))
нет прямо сказать, что в функцию swap надо передавать аргументы
издеваетесь над человеком )))
нет прямо сказать, что в функцию swap надо передавать аргументы
А перед этим объяснить, чем функция отличается цикла return.
В com-порт выводится b = 2. Но в чем отличие между тем, если бы я задал a = b ? Ведь это копирование значения одной переменной и подстановка вместо значения другой.
Отличие в том, что это не копирование, а прямая работа с областью памяти. См. "Указатели в Си"
BigMeister, какое вообще отношение ваша функция swap() имеет к той, что вам написал andriano? Его функция брала ДВА аргумента и меняла их местами, ваша - берет один и приравнивает его константе 2. Как говорится, "найдите два отличия".
Чего вы нас спрашиваете, какой смысл в вашей функции? это вы ж ее написали...
Мона ещё и так, без промежуточной переменной:
красиво, но извольте пояснить пожалуйста, в какой переменной хранится результат от XOR
так правильно?
x=XOR(x,y);
y=XOR(y,x);
x=XOR(x,y);
Это более или менее общепринятое название для функции, которая меняет между собой местами два переданных ей параметра.
Ну, примерно так:
Я прочел все статьи про передачу аргументов в си, которые нашел. Везде есть примеры про "копирование" (тот код, который я оставил выше) и объяснения к ним. Но нигде нет что-то похожего на то, что Вы написали.
Можно получить Ваш код с примером целиком ?
https://metanit.com/cpp/tutorial/3.3.php -> "Передача параметров по ссылке"
Я прочел все статьи про передачу аргументов в си, которые нашел.
А почему Вы не прочли заодно статьи по Паскалю или там Брейнфаку? Вы уж на каком языке работаете, про тот статьи и читайте.
А в С действительно нет такой передачи параметров - правильно Вы не нашли. Нельзя найти то, чего нет.
Добавлю также 1 простой метод: сравнение предыдущего значения с новым случайным значением от генератора. Если значения равны, то сразу вычисляется новое случайное значение. В массив записываете не повторяющие значения.
Добавлю также 1 простой метод: сравнение предыдущего значения с новым случайным значением от генератора. Если значения равны, то сразу вычисляется новое случайное значение. В массив записываете не повторяющие значения.
А если новому равно не предыдущее, а пред-предыдущее, или записанное в массив шагов пять назад, тогда как?
Евгений, добейте уже всех - предложите использовать ГСПЧ. Я не математик, у меня красиво не получится, а вот вы сможете...
Мона ещё и так, без промежуточной переменной:
красиво, но извольте пояснить пожалуйста, в какой переменной хранится результат от XOR
так правильно?
x=XOR(x,y);
y=XOR(y,x);
x=XOR(x,y);
В переданных переменных, очевидно. Для такой реализации swap не надо третьей, промежуточной переменной - всё происходит по месту.
Короче, мне кажется, что тут клиника :) И проще отпинаться куском кода - пущай его, что называется: нас, избранных, должно быть мало - зачем увеличивать это количество? :)
Так понимаю, следующей темой обсуждения будет вопрос, почему этот код всегда при запуске дает одно и тоже.
Ну надо же как-то заставить читать доку, про тот же randomSeed ;) Да и в этом случае распределение там - такое себе, херовенькое.
Добавлю также 1 простой метод: сравнение предыдущего значения с новым случайным значением от генератора. Если значения равны, то сразу вычисляется новое случайное значение. В массив записываете не повторяющие значения.
А если новому равно не предыдущее, а пред-предыдущее, или записанное в массив шагов пять назад, тогда как?
[/quote]
Уважаемые ЕвгенийП! Согласна с Вами. В этом случае имеется вероятность повторяющееся значение. И если это так - это плохой генератор случайных чисел.
Тогда придется сравнивать новое значение от генератора с каждым ранее записанным значением в массив. Если значения равны, то вычисляется новое случайное значение.
Добавлю также 1 простой метод: сравнение предыдущего значения с новым случайным значением от генератора. Если значения равны, то сразу вычисляется новое случайное значение. В массив записываете не повторяющие значения.
А если новому равно не предыдущее, а пред-предыдущее, или записанное в массив шагов пять назад, тогда как?
Уважаемые ЕвгенийП! Согласна с Вами. В этом случае имеется вероятность повторяющееся значение. И если это так - это плохой генератор случайных чисел.
Тогда придется сравнивать новое значение от генератора с каждым ранее записанным значением в массив. Если значения равны, то вычисляется новое случайное значение.
[/quote]
Этот метод не "простой", а "ужасный": если сложность нормального метода О(N), то у предложенного Вами он явно хуже O(N^2). Вплоть до полного зацикливания.
И еще, если у генератора вероятность повторного выпадения уже бывших ранее чисел меньше (не говоря о том, что вообще равна 0), чем у еще не выпавших, это никуда не годный генератор.
У хорошего ГСЧ в любой момент вероятность выпадания любого числа из диапазона генерируемых не зависит от того, повторное оно или нет, она const и равна 1/М, где М - число возможных значений в диапазоне генерируемых чисел. А так да, подход из #25 верный.
Добавлю также 1 простой метод: сравнение предыдущего значения с новым случайным значением от генератора. Если значения равны, то сразу вычисляется новое случайное значение. В массив записываете не повторяющие значения.
Image already added
А если новому равно не предыдущее, а пред-предыдущее, или записанное в массив шагов пять назад, тогда как?
Уважаемые ЕвгенийП! Согласна с Вами. В этом случае имеется вероятность повторяющееся значение. И если это так - это плохой генератор случайных чисел.
Тогда придется сравнивать новое значение от генератора с каждым ранее записанным значением в массив. Если значения равны, то вычисляется новое случайное значение.
Этот метод не "простой", а "ужасный": если сложность нормального метода О(N), то у предложенного Вами он явно хуже O(N^2). Вплоть до полного зацикливания.
И еще, если у генератора вероятность повторного выпадения уже бывших ранее чисел меньше (не говоря о том, что вообще равна 0), чем у еще не выпавших, это никуда не годный генератор.
[/quote]
С Вами не согласна. Зациклывания не произойдет от генратора случайных чисел.
Предложенный Вами метод, также сожержит ошибку на которую указал ЕвгенийП. Потому что в Вашем
алгоритме меняете местами заранее изветные значение счетчик-переменная `i` с генерированным значением.
и также не учитывается предыдущее значение генератора чисел.
1. Заполняете массив последовательными числами, например, a[i] = i+1;
2. Пробегаетесь циклом по массиву, меняя текущий элемент со случайным местами. swap(a[i], a[random(N)]);
Результат от Вашего не страшного алгоритм
С Вами не согласна. Зациклывания не произойдет от генратора случайных чисел.
Я не утверждал, что зацикливание непременно произойдет. Но при определенных условиях - может.
Предложенный Вами метод, также сожержит ошибку на которую указал ЕвгенийП.
Отнюдь. Он указал на ошибку в Вашем алгоритме.
Увы, не все умеют правильно записать скетч по краткому словесному описанию алгоритма. Да и в приведенном выше варианте (от которого Вы, по всей видимости, отталкивались) было две ошибки, да и Вы добавили не меньше.
Извините, пожалуйста, Мужики! Сделала ошибку, признаю свою ошибку из-за невнимательности. Не заметила, что в массиве переставляются местами элементы массива по индексу, который получен от генератора. Буду, старатся быть внимательнее.
strarbit, а Вы все-таки напишите по своему "простому методу" скетч.
Чтобы была возможность сравнить и, главное, - осознать, насколько этот метод ужасен.
Увы, не все умеют правильно записать скетч по краткому словесному описанию алгоритма. Да и в приведенном выше варианте (от которого Вы, по всей видимости, отталкивались) было две ошибки, да и Вы добавили не меньше.
Это какие - укажи плз? Если ты про это (кусок ТВОЕГО кода):
То тут как раз ошибка. Почему - достаточно почитать описание random (брал именно оттуда доку, с оффсайта):
Syntax
random(max)
random(min, max)
Parameters
min
- lower bound of the random value, inclusive (optional)max
- upper bound of the random value, exclusiveВыделил жирным. Что тебе ещё не понравилось? Тривиальный способ вычисления размерности массива в виде
sizeof(array)/sizeof(array[0]) ?
Так это совершенно нормальная операция. Возможно, метод обмена с использованием xor?
Я прочел все статьи про передачу аргументов в си, которые нашел.
А почему Вы не прочли заодно статьи по Паскалю или там Брейнфаку? Вы уж на каком языке работаете, про тот статьи и читайте.
А в С действительно нет такой передачи параметров - правильно Вы не нашли. Нельзя найти то, чего нет.
То-есть С это классика? Там нет "пойди туда не знаю куда и узнай куда идти дальше"? )))
в качестве рандом неплохо брать числа из ряда Пи после запятой (если процессор позволяет)
ua6em, четсно говоря, не понял, отвечу как понял, если что, уточняйте вопрос.
То-есть С это классика?
Это язык программирования. Он не является ни "подмножеством", ни "основой" С++ - это просто другой язык программирования.
Там нет "пойди туда не знаю куда и узнай куда идти дальше"? )))
Не знаю, насчёт указаний куда пойти :))), но там есть стандарт языка, в котором он строго и формально описан.
ua6em, четсно говоря, не понял, отвечу как понял, если что, уточняйте вопрос.
То-есть С это классика?
Это язык программирования. Он не является ни "подмножеством", ни "основой" С++ - это просто другой язык программирования.
Там нет "пойди туда не знаю куда и узнай куда идти дальше"? )))
Не знаю, насчёт указаний куда пойти :))), но там есть стандарт языка, в котором он строго и формально описан.
Женя! Это не подколка и не попытка поймать на слове.
Просто в голову не приходит ничего, что я использую в С, запрещенного в С++. Формально - да, не подмножество... void, прототипы и пр.... но из "обще"-используемого что? Так что по факту - все таки подмножество...
Строго так: Частоиспользуемое подмножество С - является подмножеством С++ ;) ;) ;)... ну, как мне каацо.
Ну, это бесконечный религиозный спор, который вести бессмысленно. С точки зрения язычника - это разные языки, а с бытовой - да, пожалуйста. В принципе, с таким же успехом можно сказать, что С в какой-то мере подмножксто Java, например, по крайней мере, у них типа есть "общие подмножества".
Кстати, можно привести примеры вполне часто, я бы даже сказал "постоянно" используемых вещей, которые работают по разному в С и С++. Т.е. синтаксически одинаковы, один и тот же текст компилируется и там, и там, а результат исполнения разный.
Вот снова я был неправильно понят... Я как раз и не хочу никакого спора, тем более, что сам согласен.
Я как раз примеры и хотел, потому, что мне в голову ничего не пришло. Не для спора, а просто "для красоты".
--------------------
А что да "как язычнику" ;), так я ж говорил, что в логику пришел от формальных грамматик и синтаксического анализа. Это немного другая сторона языков программирования, но не слишком далекая от вашей.
Щас сделаю пример.
Пихаем в директорию "kaka" два файла.
Файл kaka.ino (компилируется как С++)
файл kakaс.c (компилируется как С)
Как видим, функции kaka1 и kaka2 абсолютно идентичны, только компилируются первая как С++, а вторая как С.
Из-за того, что в С символьная константа имеет тип int, а в С++ - char (причём, это требование языка, а не прихоть компилятора), в результате, в мониторе порта, видим:
Ну Женя! Про преобразование к int ты еще с Архатом, года три назад, дискутировал... Ему очень тогда стандарт не понравился! ;) ;) ;)...
Это простой пример. Верю, что общеизвестный... хотя... ;) Я надеялся на что-то более неочевидное.
Все равно - спасибо.
Я то как раз из кожи напрягался, чтобы сделать пример как можно проще, т.к. считал, что неочевидное будет названо надуманным :)))
Неочевидное можно, мне и самому интересно сделать, но только завтра, у меня ДР сегодня, пора к пьянке готовиться.
От всей души поздравляю.
Евгений! Удачи, денег, здоровья! От души!
Спасибо, парни!
С днем рождения Женя!
Евгений Петрович! Здоровья и кавказского долголетия!!!
Евгений Петрович!
С днем рожденья Вас поздравляю
Здоровья, радости и везенья!