Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > Массив из диапозона чисел |
Автор: JAYBE 11.1.2013, 10:16 | ||||
Добрый день! Помогите, пожалуйста, с задачей: Задан числовой массив А[1:m, 1:n]. Составить программу поиска элемента массива, который является наибольшим из отрицательных чисел расположенных в строках. Мой код:
Возникает 2 вопроса. 1) Как сделать рандомный массив из дапозона, причем
2) У меня циклы 2 раза "пробегают". 1 раз при создании массив и 2-ой раз при поиске минимального элемента. Как-то можно их оптимизировать с точки зрения алгоритма в один? |
Автор: bsa 11.1.2013, 10:38 |
легко: x ∈ [-10;15] -> y ∈ [0;25], где x = (y - 10) -> y = random * 25 / RAND_MAX, где random ∈ [0;RAND_MAX]: y = (int)(25 * (rand()/(double)RAND_MAX) + 0.5); x = y - 10; |
Автор: bsa 11.1.2013, 14:04 | ||
конечно можно. посмотри на циклы - они имеют много общего. ![]() |
Автор: JAYBE 11.1.2013, 22:40 | ||
А как сделать переход к следующему шагу в цикле, есть какой-либо аналог continue в js. Тоесть так можно было бы:
|
Автор: IValdemar 11.1.2013, 23:11 | ||||
JAYBE, continue в C и C++ есть ![]()
Добавлено через 6 минут и 6 секунд вот так он выведет 1, или что-то вроде этого, если надо вывести array[i][y] тогда так:
|
Автор: volatile 12.1.2013, 00:24 | ||
Нормально выведет. Код идентичен. |
Автор: feodorv 12.1.2013, 00:41 |
А зачем здесь array[i][y]? i и y инициализированы корректно? |
Автор: IValdemar 13.1.2013, 00:28 | ||
volatile, хм действительно правильно выводит. Не знал, что так можно. Это потому что результатом операции
является элемент array[i][y]? |
Автор: volatile 13.1.2013, 23:11 | ||||||
IValdemar, в данном случае мы имеем оператор присваивания. Стандартная сигнатура этого оператора:
как видите он возвращает ссылку на объект, которому присваиваецца значение.
здесь произодицца присваивание array[i][y] случайного значения, и затем возвращаецца ссылка на array[i][y], значение которой и выводицца в стандартный вывод. --- Очевидно, что вы перепутали с оператором сравнения:
Вот он, как раз возвращает булеву переменную, как вы и описали. В языке С/С++ оператор=, и оператор==, это два разных оператора. Не нужно их путать. |
Автор: JAYBE 14.1.2013, 10:04 | ||
Спасибо. Так и не понял bsa про объяснение рандомных чисел - сделал сам. Оставил двойной проход по массиву, по учебной задаче наврное не стоит заморачиваться так с опимизацией выполнения кода. В итоге оставил так:
|
Автор: bsa 14.1.2013, 15:35 | ||
JAYBE, а что там непонятного? rand() возвращает значения от 0 для RAND_MAX включительно. Тебе же нужно от -10 до 15. Можно вынести -10 за скобку и получить от 0 до 25 включительно. Теперь нужно как-то RAND_MAX превратить в 25. Как это сделать? да очень просто - раздели результат rand() на double(RAND_MAX) (double необходим, чтобы деление было нецелочисленным) и получишь значения в диапазоне от 0 до 1 включительно. Теперь умножаешь на 25 и получаешь от 0 до 25. Осталось только вспомнить о -10. Правда, есть одна особенность, связанная с преобразованиями из double в int - при этом число округляется к ближайшему меньшему целому. Т.е. число 24.999999999999 округлится к 24. Чтобы этого избежать нужно добавить 0.5. Вот итоговая формула:
|
Автор: volatile 14.1.2013, 16:55 | ||
bsa, в данном случае лучше не прибавлять 0,5 иначе вероятность выпадения числа 0 и 25 будет в 2 раза меньше чем остальных (1...24) Если нужен диапазон от 0 до 25 включительно, лучше умножать на 26, и ничего не прибавлять. Добавлено через 8 минут и 32 секунды r = rand() % 26 - 10; |
Автор: bsa 14.1.2013, 20:02 | ||||||
в этом случае распределение неравномерно, так как RAND_MAX не делится на 26
Я вспомнил правильную формулу.
|
Автор: volatile 14.1.2013, 23:27 | ||||||
Согласен, строго говоря, там будет незначительная неравномерность. Но этой неравномерностью, в большинстве случаев можно спокойно пренебречь.
Эта формула, лишь длиннее, но ничем не лучше. Неравномерность там будет точно такая-же. ![]() Могу показать, если пожелаете. Но думаю вы сами поймете, если задумаетесь. кстати, именно потому, что ![]() Если уж нужна абсолютная равномерность, то надо делать так:
|
Автор: volatile 14.1.2013, 23:51 |
неравномерность = есть отношение выпадений самого вероятного к самому маловероятному. |
Автор: NoviceF 15.1.2013, 09:09 |
Поясните, пожалуйста, тут же ранд может вернуть 26? Что происходит в этом случае (по условию же максимум нужно 25)? |
Автор: bsa 15.1.2013, 09:35 |
NoviceF, что является результатом оператора % ? |
Автор: NoviceF 15.1.2013, 09:46 | ||
Остаток от деления того, что слева, на то, что справа. Если ранд вернёт число кратное 26, то результатом будет 0, в остальных случаях остаток будет в диапазоне от 1 до 25, так? ) |
Автор: bsa 15.1.2013, 10:08 | ||
да Тогда в чем был смысл предыдущего вопроса? volatile, ты был прав. Равномерность примерно одинаковая, что для варианта с остатком от деления, что с умножением (примерно, 99.6% и 99.7% соответственно на N*1000000 опытах).
|
Автор: volatile 15.1.2013, 23:23 | ||
bsa, уважаю! ![]() Фактически неравномерность у них меньше, здесь все забивает системный rand. Там и uniform_rnd() показывает такую-же неравномерность, а должен быть идеальным. по моим подсчетам неравномерность при N=26, для обоих методов составляет: =99.9207% для uniform_rnd: =100.0000% я эти числа получил просто счетчиком пройдя весь диапазон от 0 до RAND_MAX, и посмотрел что на выходе. Но можно пойти и другим путем, испоьзуя вашу программу. Чтобы обострить неравномерность, будем генерить числа соизмеримые с RAND_MAX, при этом неравномерность резко возрастает, и становицца видна невооруженным глазом, даже сквозь системный rand(). Итак, на вашей программе, для: N = int(0.55*RAND_MAX); и при количестве циклов 100*1000000ll результаты, такие:
при увеличении опытов norm1,norm2 стремяцца к ==> 50%; uniform_rnd ==> 100% Резюме. при маленьком N, все замечательно и вообще по барабану какую формулу использовать. При больших N, простые формулы дают очень плохую картину. Вероятность выпадения макс/мин в 2 раза, уже нельзя назвать ГСЧ. и нужно использовать генератор с отбрасыванием, такой как uniform_rnd(); |