让Fibo更快

时间:2018-11-30 20:43:31

标签: python fibonacci

我需要编写一个代码以给出一个数字并打印出F [number]。此代码相当慢。是否有更快的代码的想法?

 while True:
      n=input()
      if n=='END' or n=='end':
         break
      class Fibonacci:
            def fibo(self, n):
                if int(n) == 0:
                   return 0
                elif int(n) == 1:
                   return 1
                else:
                  return self.fibo(int(n)-1) + self.fibo(int(n)-2)
      f=Fibonacci()
      print(f.fibo(n))

5 个答案:

答案 0 :(得分:2)

我在这篇文章中写了一些关于更快斐波那契的文章,也许其中之一对您有用吗? https://sloperium.github.io/calculating-the-last-digits-of-large-fibonacci-numbers.html

无论如何。您的代码非常慢,因为您需要一遍又一遍地调用相同的子树以指数方式运行。

您可以尝试线性解决方案:

this

答案 1 :(得分:2)

您可以使用functools memoize使其存储以前的值,这样就不必递归调用fibonacci函数。他们列出的示例实际上是斐波那契

答案 2 :(得分:1)

您可以使用字典来记住该功能:

memory = {0:0, 1:1}
def fibo(n):
    if n in memory:
        return memory[n]
    else:
        ans = fibo(int(n)-1) + fibo(int(n)-2)
        memory[n] = ans
        return ans

答案 3 :(得分:1)

使用动态编程:这样可以防止每次都一直计算到0和1:

>>> fibo(1000)
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

测试:

    If lstBox.ItemsSelected.Count > 0 Then
    lstVar = lstBox.ItemData(i)
    Debug.Print VarType(lstVar)
    For Each varItem In lstBox.ItemsSelected
        strCrit = strCrit & "," & "'" & lstBox.ItemData(varItem) & "'"
    Next varItem

    ' remove first comma
    strCrit = Mid(strCrit, 2)

这几乎是瞬时的。

答案 4 :(得分:1)

  1. 请勿使用class;您没有从中获得任何好处
  2. 不必在每个循环中重新定义类
  3. strint一次转换,而不是一遍又一遍
  4. (如果作业没有要求)使用迭代解决方案,而不是递归

仅用#1-3,您将得到:

def fibo(n):   # Using plain function, defined once outside loop
    if n < 2:
        return n
    return fib(n - 1) + fibo(n - 2)

while True:
    n = input()
    if n.lower() == 'end':
        break
    print(fibo(int(n)))  # Convert to int only once

如果不需要使用递归解决方案,则不要;斐波那契生成实际上是一种非常糟糕的递归用法,因此将函数重新定义为:

def fibo(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

执行O(n)工作而不是O(2**n)工作。记忆化可以加快递归解决方案的速度(通过用fibo装饰@functools.lru_cache(maxsize=None)),但是当迭代解决方案的速度快得多并且一开始就不需要缓存时,就不值得麻烦了。