繁体   English   中英

斐波那契序列计算器python

[英]Fibonacci sequence calculator python

嗨,我是python的新手,尝试创建一个Fibonacci计算器函数,该函数将所有值打印到给定的数字,如果输入的数字不在序列中,则它将下一个Fibonacci数字添加到列表中。 例如,如果输入10,则应返回[0, 1, 1, 2, 3, 5, 8, 13] 该函数必须是递归的。 这是我当前的代码:

def fibonacci(n):
    n = int(n)
    # The nested sub_fib function computes the Fibonacci sequence

    def sub_fib(n):
        if n < 2:
            return n
        else:
            return (sub_fib(n-1) + sub_fib(n-2))

    #This aspect of the main fib function applies the condition if the number
    # input is not in the sequence then it returns the next value up

    fib_seq= [sub_fib(i) for i in range(0,n) if sub_fib(i)<=n]
    if fib_seq[-1] < n:
        fib_seq.append(fib_seq[-1] + fib_seq[-2])
        return fib_seq
    else:
        return fib_seq
print(fibonacci(input("Input a number to print sequence up to: ")))

我设法使其正常工作,但它的运行速度极其慢(我认为是由于递归),有什么办法可以在不进行大量更改的情况下加快速度吗?

您的程序运行缓慢的两个主要原因:

  • 单独计算每个Fibonacci数,你不重用你投资在寻找上一个数字的努力;
  • 您可以计算前n个斐波那契数,但是从条件失败的那一刻起,您可以停止

您可以将程序更改为递归,但可以重复使用工作来计算先前的数字,并从构造列表的那一刻起停止。

您只需要使用以下功能:

def fibon(a,b,n,result):
    c = a+b
    result.append(c)
    if c < n:
        fibon(b,c,n,result)
    return result

然后用以下fibon(0,1,n,[])初始化它: fibon(0,1,n,[]) 在每次迭代中,它将计算下一个斐波那契数c = a+b并将其附加到result 如果该数字仍然小于c < n那么我们需要计算下一个数字,然后执行递归调用。

def fibonacci(n):
    n = int(n)

    def fibon(a,b,n,result):
        c = a+b
        result.append(c)
        if c < n:
            fibon(b,c,n,result)
        return result

    return fibon(0,1,n,[])

print(fibonacci(input("Input a number to print sequence up to: ")))

这使用了递归,但是比幼稚的递归实现要快得多

def fib(n):
    if n == 1:
        return [1]
    elif n == 2:
        return [1, 1]
    else:
        sub = fib(n - 1)
        return sub + [sub[-1] + sub[-2]] 

以下是一些如何提高速度的示例:

"""
Performance calculation for recursion, memoization, tabulation and generator

fib took: 27.052446
mem_fib took: 0.000134
tabular_fib took: 0.000175
yield_fib took: 0.000033
"""
from timeit import timeit


LOOKUP_SIZE = 100
number = 30
lookup = [None] * LOOKUP_SIZE


def fib(n):
    return 1 if n <= 2 else fib(n - 1) + fib(n - 2)


def mem_fib(n):
    """Using memoization."""
    if n <= 2:
        return 1
    if lookup[n] is None:
        lookup[n] = mem_fib(n - 1) + mem_fib(n - 2)

    return lookup[n]


def tabular_fib(n):
    """Using Tabulation."""
    results = [1, 1]
    for i in range(2, n):
        results.append(results[i - 1] + results[i - 2])
    return results[-1]


def yield_fib(n):
    """Using generator."""
    a = b = 1
    yield a
    yield b
    while n > 2:
        n -= 1
        a, b = b, a + b
        yield b


for f in [fib, mem_fib, tabular_fib, yield_fib]:
    t = timeit(stmt=f"f({number})", number=10, globals=globals())
    print(f"{f.__name__} took: {t:.6f}")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM