но правильна ли реализация?
Нет. Даже если вы включите исправление @ ExplodingGayFish, оно скрывает тот факт, что ваша логика запоминания нарушена. Например:
...
#Defining mem as a list
mem = [1]
print(fibo(5))
print(mem)
print(fibo(4))
print(mem)
Вы получаете правильный ответ, но выполняете всю работу снова:
> python3 test.py
5
[1, 1, 1, 2, 1, 3, 1, 1, 2, 5]
3
[1, 1, 1, 2, 1, 3, 1, 1, 2, 5, 1, 1, 2, 1, 3]
>
Это связано с неправильным обращением с массивом mem
, включаяэтот тест:
if len(mem) == n :
, который действительно должен быть больше , а не равно . Решение на самом деле проще, чем ваш неработающий код:
def fibo(n, memory=[0]): # intentional dangerous default
if len(memory) > n:
return memory[n]
if n == 1:
res = 1
else:
res = fibo(n - 1) + fibo(n - 2)
memory.append(res)
return res
Однако, даже при множественных вызовах fibo(900)
, хороший рекурсивный алгоритм , подобный следующему:
def fibo(n, res=0, nxt=1):
if n == 0:
return res
return fibo(n - 1, nxt, res + nxt)
будет соответствовать скорости моей исправленной версии вашего кода даже без напоминания! И ни один не достигнет fibo(1000)
без расширения стека Python из-за глубины рекурсии. (Вот почему было бы лучше запоминать итеративное решение.)