![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
observateur |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 176 Регистрация: 10.6.2006 Репутация: нет Всего: нет |
Заранее спасибо тем кто ответить...Самостоятолна изучаю C++. помогите пожалоста понять как работает Рекурсивная функция. Уменя есть книга Х.М.Дейтель "Как программировать на С++". Все равно трудно понять суть рекурсии.
![]() |
|||
|
||||
Xenon |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Что значит КАК? Ну функция из самой себя вызывает саму себя с новым аргументом
![]() ![]() ![]() Вот нахождение факториала простым способом
Вот пр помощи рекрусси:
Это сообщение отредактировал(а) XenonSk - 10.6.2006, 12:58 |
||||
|
|||||
observateur |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 176 Регистрация: 10.6.2006 Репутация: нет Всего: нет |
Я знаю условия цикла рекурсивный функции. мне надо схема ее рабаты. Точнее схематический как она работает. спасибо за вашу терпению
|
|||
|
||||
AlanG |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Так все спрашивают, когда начинаю ![]() ![]() ![]() А думать о схеме не надо, вот как это происходит
Вообще все вызовы сохраняются в стеке, и каждому вызову присваивается значение с помощбю return Это сообщение отредактировал(а) AlanG - 10.6.2006, 13:28 |
||||
|
|||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
XenonSk, 0! = 1.
На примере того же факториала: Мы знаем рекуррентное соотношение (которое, кстати, лежит в основе каждой рекурсивной функции): fact (n) = n * fact (n - 1). Вот мы это и реализуем: в предположении, что наша функция вычисляет факториал, пишем, что "n! = n(n - 1)!". При этом мы уверены, что (n - 1)! будет вычислен правильно. На основе этого получаем то, что надо. Это сообщение отредактировал(а) Pete - 10.6.2006, 14:26 -------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
AlanG |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
А ноль для интереса прибавил, или чтобы начинающего запутать ![]()
Перевод будет? ![]() |
||||
|
|||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Pete, Ну и?
![]() |
|||
|
||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
Поправил)
-------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Млин, я 0!=1 прочитал, как : "Нуль не равен единице" ...
![]() Тогда уж:
Это сообщение отредактировал(а) XenonSk - 10.6.2006, 14:32 |
|||
|
||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
Это не что иное, как оптимизация. Если говорить бо оптимизации, то вычисление факториала с помощью рекурсии гораздо дороже итеративного варианта и выйгрыша почти никакого.
-------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
observateur |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 176 Регистрация: 10.6.2006 Репутация: нет Всего: нет |
Спасибо всем кто отвечал. Постараюс понять.
|
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
я бы сказал вообще никакого ![]() -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Хвостовая рекурсия эквивалентна итерации (точнее, наоборот). В приведенном коде рекурсия не хвостовая, но легко к ней сводится. Так что разница в способе вычисления тут скорее не алгоритмическая, и все зависит от прозорливости оптимизатора ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
Небольшой есть. Время работы рекурсивной программы никогда не будет эквивалентно ее итерационной версии (именно с прикладной точки зрения), ибо сам процесс вызова функции очень дорог, не говоря уж об ограниченности стека и т.п. А если компилятор умеет распознать рекурсию, то это исключительно его достоинство, а не достоинство метода. Тем более, один это дело оптимизирует, а другой --- нет. На такие вещи, по-моему, нельзя надеяться. Это сообщение отредактировал(а) Pete - 10.6.2006, 18:07 -------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Есть алгоритмы, которые рекурсивны по своей природе, и для их итеративной реализации придется организовывать собственный стек. Сомнительный выигрыш. В С++ — нельзя, согласен. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
Скажем так: любой рекурсивный алгоритм из Кормена, насколько я их помню, можно переписать в итерационном виде с увеличением быстродействия. Если ты имеешь в виду что-то, быть может, экзотическое, то прошу в студию. ![]() -------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Pete, ничего экзотического, перепиши обычную быструю сортировку (Хоара), не создавая собственного стека.
И сравни быстродействие эмуляции стека с явной рекурсией. Такой вариант, возможно, окажется быстрее, но ненамного. И даже в этом я не уверен. Это сообщение отредактировал(а) Void - 10.6.2006, 18:23 -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Pete |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 318 Регистрация: 5.1.2006 Где: Москва Репутация: нет Всего: 12 |
Хм.. Согласен. Пока не встречал ее итерационной реализации без стека. Сравнение этих алгоритмов в скорости, наверное, уже больше зависит от системы. Конечно, отсутствие объявления новых переменных на каждом уровне рекурсии придаст определенное ускорение, хотя, кто знает...
(ЗЫ: мы пока от темы не ушли далеко? ![]() Это сообщение отредактировал(а) Pete - 10.6.2006, 18:45 -------------------- Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу) Не откладывай на завтра то, что можешь сделать сегодня. (Пословица) А теперь выпишем точное значение числа пи... (Препод) Жахни, Пендальф! © Гоблин |
|||
|
||||
Xenon |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Ну мне кажется тут такой же "большой" прирост в скорости, что и при использовании
Вместо
|
||||
|
|||||
kirjanov |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 326 Регистрация: 22.1.2006 Где: Dark wood of erro r Репутация: 1 Всего: 15 |
XenonSk,
конечно, прирост производительности явно не будет большим. Может твой компилятор и сгенерирует эквивалентный код, как в верхней инструкции. Что может быть более показательным сейчас, как использование интерпретируемых языков.... |
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
kirjanov, То, что кинул я считается не одним и тем же ... Вообще говорят, что часто побитовый сдвиг дает хороший прирост
![]() |
|||
|
||||
Void |
|
||||||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Я не знаю компилятора, настолько тупого, чтобы умножение или деление на константу он не превратил в битовый сдвиг. И, кстати, в случае знакововых чисел можно сильно огрести, использовав сдвиг вправо вместо деления:
И еще:
Это Intel C++ 9.0 в режиме максимальной оптимизации. Не оптимизируйте, и не оптимизируемы будете ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||||||
|
|||||||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Void, просто говорю, что в справочнике написано, а об "вылезании" там тоже писали
![]() |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
думаю вариант с эмуляцией будет быстрее насколько я знаю при рекурсивном вызове в стек заносится все окружение (локальные переменные) и адрес возврата при эмуляции заносятся лишь необходимые данные при быстрой организации нашего стека (например статический массив) думаю он будет по-эффективнее явной рекурсии -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Void |
|
||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
В стек заносится лишь адрес возврата и параметры вызываемой функции. Да, вызываемая функция выделяет место на стеке для своих локальных переменных, но это — одна инструкция изменения регистра стека.
Кажется, уже обсуждалось, что статические переменные не могут дать никакого преимущества в скорости перед локальными. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||
|
|||||
MAKCim |
|
||||||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
я это и имел в виду, не так выразился
под статическим массивом я подразумевал массив на стеке (размер известен в compile-time) как пример можно взять рекурсивную функцию
и эквивалентную ее итеративную с эмуляцией стека
и вызов
тут итеративная выигрывает в используемой памяти (261 против 512 байт) и по количеству команд процессора (326 против 575 (вывод считаем оной командой; командную реализацию while и if не рассматриваем)) так как любая рекурсивная программа сводится к итеративной, то, как показывает пример, при правильной ее организации она оказывается более эффективной Это сообщение отредактировал(а) MAKCim - 12.6.2006, 09:42 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||||||
|
|||||||||||
Void |
|
||||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Эх, люблю я бенчмарки проводить
![]()
Результаты: GCC 3.4.5 (MinGW)
VC 8.0:
Вот такая забавная картина, не находите? ![]() Так стоит ли заморачиваться с ручной эмуляцией стека ради пары процентов производительности, которые в зависимости от компилятора могут оказаться и на той, и на другой стороне? ИМХО, нет. В данном случае можно было оценить верхний предел глубины рекурсии, однако выделяя под стек массив постоянного размера мы в любом случае рискуем молчаливо вылететь за его пределы. Используя же динамический массив мы рискуем свести на нет все призрачные преимущества эмуляции рекурсии. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |