【问题标题】:What would be the best answer for this Fibonacci excercise in Python?在 Python 中这个斐波那契练习的最佳答案是什么?
【发布时间】:2016-05-20 14:24:54
【问题描述】:

在 Python 中这个斐波那契练习的最佳答案是什么?

http://www.scipy-lectures.org/intro/language/functions.html#exercises

练习:斐波那契数列

编写一个函数,显示斐波那契的第 n 个第一项 序列,定义:

  • u0 = 1; u1 = 1

  • u(n+2) = u(n+1) + un

如果这只是询问斐波那契代码,我会这样写:

def fibo_R(n):
    if n == 1 or n == 2:
        return 1
    return fibo_R(n-1) + fibo_R(n-2)
print(fibo_R(6))

... 但是,在这个练习中,初始条件都是 1 和 1,并且计算正朝着正方向 (+)。我不知道如何设置结束条件。我已经搜索了答案,但我找不到任何答案。你会怎么回答这个问题?

【问题讨论】:

  • 在python主站有解决方案python.org
  • 您编写了一个函数来仅获取第 n 个元素。他们要求第一个 n,因此当您可以在之前的结果的基础上构建时,您将重复计算每个元素的大量工作。
  • 一个词:记忆。
  • stackoverflow.com/questions/36948082/… 有一些关于定义斐波那契数列的不同方法的相关讨论。

标签: python recursion fibonacci


【解决方案1】:

请注意,u_(n+2) = u_(n+1) + u_n 等同于 u_n = u_(n-1) + u_(n-2),即您之前的代码仍然适用。斐波那契数的定义是根据其前身定义的,无论您如何表述问题。

解决这个问题的一个好方法是定义一个generator,它按需生成斐波那契数列的元素:

def fibonacci():
    i = 1
    j = 1

    while True:
        yield i
        x = i + j
        i = j
        j = x

然后您可以通过例如first N items of the generator itertools.islice,或者您使用enumerate 来跟踪您看到的数字:

for i, x in enumerate(fibonacci()):
  if i > n:
    break
  print x

拥有一个生成器意味着您可以使用相同的代码来解决许多不同的问题(尽管效率很高),例如:

  • 获取第 n 个斐波那契数
  • 获取前 n 个斐波那契数
  • 获取满足某个谓词的所有斐波那契数(例如,所有低于 100 的斐波那契数)

【讨论】:

  • 我将您的答案作为最佳答案,因为您提到“u_(n+2) = u_(n+1) + u_n 等价于 u_n = u_(n-1) + u_(n -2)",初始条件为 i=1,j=1。我太依赖递归了,但你让我意识到了这一点。非常感谢!
【解决方案2】:

计算斐波那契数列的最佳方法是简单地从头开始并循环,直到计算出第 n 个数。递归会产生太多的方法调用,因为您一遍又一遍地计算相同的数字。

这个函数计算第一个n斐波那契数,将它们存储在一个列表中,然后将它们打印出来:

def fibonacci(n):
    array = [1]
    a = 1
    b = 1
    if n == 1:
        print array
    for i in range(n-1):
        fib = a + b
        a = b
        b = fib
        array.append(fib)
    print array

【讨论】:

  • 有一种方法是公式,它使用 O(1) 内存和时间。我猜练习(我不会拼写)意味着递归方式。
  • 任务是计算前n个斐波那契数,而不仅仅是第n个数。仅用 n 个元素填充列表需要 O(n)
  • @AmitGold 练习描述中没有任何内容要求使用递归。
【解决方案3】:

如果您想要一个超级节省内存的解决方案,请使用仅按需生成下一个数字的生成器:

def fib_generator():
  e1, e2 = 0, 1
  while True:
    e1,e2 = e2, e1+e2
    yield e1

f = fib_generator()
print(next(f))
print(next(f))
print(next(f))
## dump the rest with a for-loop
for i in range(3, 50):
  print(next(f))

递归解决方案是最优雅的,但它很慢。 Keiwan 的循环对于大量元素来说是最快的。

是的,绝对没有 DSM 正确观察到的全局变量。谢谢!

【讨论】:

  • 为什么要使用全局变量?
  • 附注:使用全局变量通常会很慢;上课会好很多。
【解决方案4】:

另一种递归只是为了表明事情可以以稍微不同的方式完成:

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

【讨论】:

    猜你喜欢
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2011-09-30
    • 2018-11-18
    • 2014-05-23
    • 2014-10-20
    • 1970-01-01
    相关资源
    最近更新 更多