Ну, они оба рекурсия, потому что вы вызываете функцию a()
внутри себя. Итак, основное различие в обеих ваших функциях состоит в том, что есть два рекурсивных вызова для первого и только один для второго.
Итак, теперь по другому вопросу:
Выше код становится очень медленным примерно за 50-й срок.
Что ж, вы можете сделать что-то интересное, чтобы сделать это быстрее. Видите, из-за рекурсивного определения последовательности Фибоначчи, вы выполняете одни и те же вычисления более чем один.
Например: представьте, что вы должны вычислить fibonacci(5)
, поэтому вам нужно вычислить fibonacci(4)
и fibonacci(3)
. Но теперь для fibonacci(4)
вам нужно вычислить fibonacci(3)
и fibonacci(2)
и так далее. Но подождите, когда вы закончите sh вычисления fibonacci(4)
ветви, вы уже вычислили все Фибоначчи для 3 и 2, поэтому, когда вы go вернетесь к другой ветви (fibonacci(3)
) из первого рекурсивного вызова, вы уже вычислили Это. Итак, что, если есть способ сохранить эти вычисления, чтобы я мог получить к ним доступ быстрее? Вы можете сделать это с помощью Decorators , чтобы создать класс memoize (своего рода память, чтобы избежать повторных вычислений):
Таким образом, мы будем хранить каждое вычисление fibonacci(k)
для dict
, и мы будем каждый раз перед вызовом проверять, существует ли он в словаре, возвращать, если True
, или вычислять его. Этот способ быстрее
class memoize:
def __init__(self, function):
self.f = function
self.memory = {}
def __call__(self, *args):
if args in self.memory:
return self.memory[args]
else:
value = self.f(*args)
self.memory[args] = value
return value
@memoize
def fib(n):
if n <= 1:
return n
else:
return fib(n-1) + fib(n-2)
r = fib(50)
print(r)
Вы можете видеть, что без памятка это заняло слишком много времени, а с памятка это заняло 0.263614
.
Надеюсь, это поможет