|
Рекурсивый алгоритм Вычисления фибоначи | ☑ | ||
---|---|---|---|---|
0
free dude
20.02.19
✎
13:13
|
Допустим в 1 коробке лежит 1 яблоко, во второй коробке лежит первая коробка. В третей коробке лежит первая и вторая коробка т.е. К2 = 1, К1 = 1; К3 = К2 + К1 = 2 яблока . К4 = К3 + К2 = 3 яблока. т.е. Кn = (Кn - 1) + (Kn-2). Почему алгоритм
function fib(n) { if (n <= 1) { console.log(n) return n } else { return fib(n - 1) + fib(n - 2); } } console.log(fib(7)); // 13 выдает последовательность с нулями, ведь в коробках всегда лежит, хотя бы 1 яблоко и пустых коробок нет? 1 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 13 причем для fib(5) - 3 нуля. для fib(6) - 5 нулей. а для fib(7) = 8 нулей. Я разобрался, но хотелось бы еще объяснения послушать. |
|||
1
ДенисЧ
20.02.19
✎
13:22
|
Всё правильно. Ты же сообщение только при <= 0 выводишь.
|
|||
2
Вафель
20.02.19
✎
13:24
|
разве fib(0) = 1 ?
|
|||
3
free dude
20.02.19
✎
13:25
|
(1) да понятно, что правильно. В первом члене 1, во втором члене 1, в третьем члене 1 + 1, в четвертом члене 1 + 1 + 1 в пятом члене 1 + 1 + 1 + 1 + 1. В шестом 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1. В седьмом 13 едениц и так далее. Откуда 0? Решение не программное а математическое
|
|||
4
free dude
20.02.19
✎
13:25
|
(2) красавец
|
|||
5
ДенисЧ
20.02.19
✎
13:25
|
(2) (последовательность A000045 в OEIS),
в которой первые два числа равны либо 1 и 1, либо 0 и 1 |
|||
6
ДенисЧ
20.02.19
✎
13:26
|
(3) fib(n - 2) при n = 1 ...
|
|||
7
free dude
20.02.19
✎
13:27
|
(5) прикол в том, что в ряд начианется с 0, и второй член состоит из 1го и нулевого. И везде где встречается второй член он дает 1 и 0.
|
|||
8
free dude
20.02.19
✎
13:30
|
Я думал, может еще какое то умное объяснение есть.
|
|||
9
K1RSAN
20.02.19
✎
13:43
|
Все просто - в коде ты возвращаешь N, которое рекурсивно в итоге становится равно 0.
if (n <= 1) { console.log(n) return n Если N <= 1, тогда возвращает N, но когда рекурсией ты ищешь fib(2) программа вычисляет fib(1) и fib(0). В первом случае он вернет 1, во втором случае вернет 0. Вот и всё, обычная ошибка в алгоритме |
|||
10
Конструктор1С
20.02.19
✎
13:44
|
Не используйте рекурсию для факториалов и чисел Фибоначчи
Одна из проблем с учебниками по вычислительной технике в том, что они предлагают глупые примеры рекурсии. Типичными примерами являются вычисление факториала или последовательности Фибоначчи. Рекурсия — мощный инструмент, и очень глупо использовать ее в этих двух случаях. Если бы программист, работающий у меня, применял рекурсию для вычисления факториала, я бы нанял кого-то другого. Вот рекурсивная версия вычисления факториала: Пример неправильного решения: вычисления факториала с помощью рекурсии (Java) int Factorial( int number ) { if ( number == 1 ) { return 1; } else { return number * Factorial( number - 1 ); } } Не считая медленного выполнения и непредсказуемого использования памяти, рекурсивный вариант функции трудней для понимания, чем итеративный вариант: Пример правильного решения: использование итераций для вычисления факториала (Java:) int Factorial( int number ) { int intermediateResult = 1; for ( int factor = 2; factor <= number; factor++ ) { intermediateResult = intermediateResult * factor; } return intermediateResult; } Из этого примера можно усвоить три урока. Первый: учебники по ВычТеху не оказывают миру услугу своими примерами рекурсии. Второй, и более важный: рекурсия — гораздо более мощный инструмент, чем можно предположить из сбивающих с толку примеров расчета факториала и чисел Фибоначчи. Третий — самый важный: вы должны рассмотреть альтернативные варианты перед использованием рекурсии. Иногда один способ работает лучше, иногда — другой. Но прежде чем выбрать какой-то один, надо рассмотреть оба. (с) С.Макконел, "Совершенный код" |
|||
11
K1RSAN
20.02.19
✎
13:49
|
Я бы предложил в рекурсии сначала искать это значение в массиве, если нет - тогда идем в более младший элемент, который есть в массиве. И новый элемент записываешь в массив. В итоге рекурсия не будет заходить так далеко, а всегда смотреть значение предыдущего и до него элементы в массиве. Ну а для первых элементов задать исключение, где указать, что они равны 1.
|
|||
12
free dude
20.02.19
✎
13:50
|
(10) может мне интересно знать, сколько нулей входит в fib(50)? Есть какая то формула? Алгоритм, кроме рекурсивного?
|
|||
13
K1RSAN
20.02.19
✎
13:55
|
(12) В чем смысл использовать неправильный алгоритм?
|
|||
14
free dude
20.02.19
✎
13:57
|
(9) это не ошибка. ряд начинается с нуля. Нулевой член равен 0. Второй член состоит из 1го и нулевого. И везде, где в дереве встречается второй член, он дает 1 и 0, а не просто 1.
|
|||
15
free dude
20.02.19
✎
14:00
|
(13) а в чем смысл любой алгоритм использовать хоть в цикле, хоть в массиве? вычисление произвольного N члена фибоначи нафиг ни кому не нужно. Возьми листик, нарисуй дерево, оно красивое. Для красоты нужно.
|
|||
16
K1RSAN
20.02.19
✎
14:01
|
(14) Третий элемент состоит из первого и второго, КОТОРЫЕ УЖЕ НЕ РАВНЫ 0. Это алгоритм по расчету ряда фибоначчи или это алгоритм рекурсии ради рекурсии?
|
|||
17
K1RSAN
20.02.19
✎
14:02
|
(15) Красивый аргумент (нет). Ладно, используй свой косячный алгоритм сколько влезет. Только не лезь с ним к людям, а держи его как свою "прееелееессссть" подальше от всех.
|
|||
18
K1RSAN
20.02.19
✎
14:06
|
Просто представь. в Таком исполнении для расчета значения допустим сотого элемента ряда твоему алгоритму придется сделать на порядок больше итераций, чем алгоритму, который будет запоминать каждый следующий элемент ряда и записывать их в массив, из которого найдет на следующем шаге нужные значения.
|
|||
19
free dude
20.02.19
✎
14:26
|
(18) Трудно быть богом.
|
|||
20
Salimbek
20.02.19
✎
14:27
|
(18) Зачем массив?
А=1 Б=1 Пока сч<н цикл С=А+Б А=Б Б=С сч=сч+1 КонецЦикла |
|||
21
Timon1405
20.02.19
✎
14:34
|
||||
22
K1RSAN
20.02.19
✎
14:58
|
(20) Ну ему же рекурсия нужна. Может тоже костыль, но массив более надежно выглядит чем эта куча нулей и единиц
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |