Имя: Пароль:
IT
 
Рекурсивый алгоритм Вычисления фибоначи
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) Ну ему же рекурсия нужна. Может тоже костыль, но массив более надежно выглядит чем эта куча нулей и единиц