Làm thế nào để viết chuỗi Fibonacci?


140

Ban đầu tôi đã mã hóa chương trình sai. Thay vì trả về các số Fibonacci giữa một phạm vi (ví dụ: startNumber 1, endNumber 20 nên = chỉ những số đó trong khoảng từ 1 đến 20), tôi đã viết cho chương trình để hiển thị tất cả các số Fibonacci giữa một phạm vi (ví dụ: startNumber 1, endNumber 20 hiển thị = 20 số Fibonacci đầu tiên). Tôi nghĩ rằng tôi đã có một mã số chắc chắn. Tôi cũng không thấy lý do tại sao điều này xảy ra.

startNumber = int(raw_input("Enter the start number here "))
endNumber = int(raw_input("Enter the end number here "))

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

print map(fib, range(startNumber, endNumber))

Ai đó đã chỉ ra trong Phần II của tôi (đã bị đóng vì là một bản sao - /programming/504193/how-to-write-the-fiborie-fterence-in-python-part-ii ) mà tôi cần truyền startNumber và endNumber thông qua trình tạo bằng vòng lặp while. Ai đó có thể vui lòng chỉ cho tôi hướng làm thế nào để làm điều này? Bất kỳ trợ giúp đều được chào đón.


Tôi là một lập trình viên học tập và tôi đã gặp một chút lộn xộn. Tôi được yêu cầu viết một chương trình sẽ tính toán và hiển thị Chuỗi của Fibonacci bởi một người dùng đã nhập số bắt đầu và số kết thúc (ví dụ: startNumber = 20 endNumber = 100 và nó sẽ chỉ hiển thị các số giữa phạm vi đó). Mẹo nhỏ là sử dụng nó một cách toàn diện (điều mà tôi không biết cách thực hiện trong Python? - Tôi giả sử điều này có nghĩa là sử dụng phạm vi bao gồm?).

Những gì tôi có cho đến nay không phải là mã hóa thực tế mà là:

  • Viết công thức chuỗi Fib đến vô hạn
  • Hiển thị startNumber thành endNumber chỉ từ chuỗi Fib.

Tôi không biết bắt đầu từ đâu và tôi đang hỏi ý tưởng hoặc cái nhìn sâu sắc về cách viết này. Tôi cũng đã cố gắng viết diễn đàn trình tự Fib nhưng tôi cũng bị lạc về điều đó.

Câu trả lời:


257

Có rất nhiều thông tin về Chuỗi Fibonacci trên wikipedia và trên wolfram . Nhiều hơn bạn có thể cần. Dù sao, đó là một điều tốt để tìm hiểu làm thế nào để sử dụng các tài nguyên này để tìm (nhanh chóng nếu có thể) những gì bạn cần.

Viết công thức chuỗi Fib đến vô hạn

Trong toán học, nó được đưa ra dưới dạng đệ quy:

Dailymotion từ wikipedia

Trong lập trình, vô hạn không tồn tại. Bạn có thể sử dụng một hình thức đệ quy dịch trực tiếp biểu mẫu toán học bằng ngôn ngữ của bạn, ví dụ như trong Python, nó trở thành:

def F(n):
    if n == 0: return 0
    elif n == 1: return 1
    else: return F(n-1)+F(n-2)

Hãy thử nó bằng ngôn ngữ yêu thích của bạn và thấy rằng hình thức này đòi hỏi nhiều thời gian vì n trở nên lớn hơn. Trong thực tế, đây là O (2 n ) trong thời gian.

Tiếp tục trên các trang web tôi liên kết với bạn và sẽ thấy điều này (trên wolfram ):

Phương trình Fibonacci

Cái này khá dễ thực hiện và rất, rất nhanh để tính toán, trong Python:

from math import sqrt
def F(n):
    return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))

Một cách khác để làm điều đó là theo định nghĩa (từ wikipedia ):

Số đầu tiên của chuỗi là 0, số thứ hai là 1 và mỗi số tiếp theo bằng tổng của hai số trước của chính chuỗi đó, thu được chuỗi 0, 1, 1, 2, 3, 5, 8 , Vân vân.

Nếu ngôn ngữ của bạn hỗ trợ các trình vòng lặp, bạn có thể làm một cái gì đó như:

def F():
    a,b = 0,1
    while True:
        yield a
        a, b = b, a + b

Hiển thị startNumber thành endNumber chỉ từ chuỗi Fib.

Khi bạn biết cách tạo số Fibonacci, bạn chỉ cần quay vòng qua các số và kiểm tra xem chúng có xác minh các điều kiện đã cho không.

Giả sử bây giờ bạn đã viết af (n) trả về số hạng thứ n của Chuỗi Fibonacci (giống như với sqrt (5))

Trong hầu hết các ngôn ngữ, bạn có thể làm một cái gì đó như:

def SubFib(startNumber, endNumber):
    n = 0
    cur = f(n)
    while cur <= endNumber:
        if startNumber <= cur:
            print cur
        n += 1
        cur = f(n)

Trong python Tôi sử dụng mẫu lặp và đi cho:

def SubFib(startNumber, endNumber):
    for cur in F():
        if cur > endNumber: return
        if cur >= startNumber:
            yield cur

for i in SubFib(10, 200):
    print i

Gợi ý của tôi là học cách đọc những gì bạn cần. Project Euler (google cho nó) sẽ đào tạo bạn làm như vậy: P Chúc may mắn và vui vẻ!


1
Bạn cần sử dụng một vòng lặp while, không phải bản đồ. Cố gắng tự mình tìm ra nó, sau đó quay lại với mã nếu bạn không thể làm được. Tôi không lười biếng (mã ngắn hơn bình luận này). Tôi đang làm điều đó cho bạn, hãy thử với gợi ý "trong khi";) Nếu bạn gặp vấn đề với điều đó hãy quay lại lần nữa;)
Andrea Ambu

Tôi đã trở lại, lol. Tôi đã thoát khỏi hàm map (phạm vi) và chỉ sử dụng một hàm phạm vi (startNumber, endNumber). Bây giờ vấn đề tôi có là sử dụng câu lệnh while ở đâu. Tôi thử ở đầu hàm nhưng tất nhiên có một lỗi xảy ra. Tôi nên đặt nó ở đâu? Thx
SD.

Cố gắng làm, bằng tay, một ví dụ về đầu vào-đầu ra của chương trình của bạn (với một phạm vi ngắn). Hãy thử sau đó để tìm ra chương trình của bạn sai ở đâu. Cố gắng chuyển đổi "phương thức thủ công" trong mã. Đây là để tập thể dục, để học hỏi. Tôi có thể đặt hai dòng mã nhưng tôi không nghĩ bạn sẽ học được gì từ chúng.
Andrea Ambu

1
Chúng ta nên sử dụng int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))), ý tưởng nào? @AndreaAmbu
chúa63. j

3
@ lord63.j, bạn chỉ nên sử dụng công thức đó nếu bạn biết rằng nó bắt đầu lệch khỏi giá trị thực khi ntrên 70 và nổ tung với mức OverflowError khi ncao hơn 600. Các cách tiếp cận khác có thể xử lý n1000 hoặc hơn mà không thổi lên hoặc mất độ chính xác.
cdlane

66

Trình tạo Pythonic hiệu quả của chuỗi Fibonacci

Tôi đã tìm thấy câu hỏi này trong khi cố gắng để có được thế hệ Pythonic ngắn nhất của chuỗi này (sau đó nhận ra rằng tôi đã thấy một câu hỏi tương tự trong Đề xuất cải tiến Python ) và tôi không nhận thấy ai khác đưa ra giải pháp cụ thể của mình (mặc dù câu trả lời hàng đầu trở nên gần gũi, nhưng vẫn kém thanh lịch), vì vậy đây là, với các bình luận mô tả lần lặp đầu tiên, bởi vì tôi nghĩ rằng điều đó có thể giúp người đọc hiểu:

def fib():
    a, b = 0, 1
    while True:            # First iteration:
        yield a            # yield 0 to start with and then
        a, b = b, a + b    # a will now be 1, and b will also be 1, (0 + 1)

và cách sử dụng:

for index, fibonacci_number in zip(range(10), fib()):
     print('{i:3}: {f:3}'.format(i=index, f=fibonacci_number))

in:

  0:   0
  1:   1
  2:   1
  3:   2
  4:   3
  5:   5
  6:   8
  7:  13
  8:  21
  9:  34
 10:  55

(Đối với mục đích phân bổ, gần đây tôi nhận thấy một triển khai tương tự trong tài liệu Python trên các mô-đun, thậm chí sử dụng các biến abbây giờ tôi nhớ lại đã thấy trước khi viết câu trả lời này. Nhưng tôi nghĩ câu trả lời này thể hiện cách sử dụng ngôn ngữ tốt hơn.)

Xác định đệ quy

Từ điển bách khoa toàn thư về chuỗi số nguyên xác định theo trình tự Fibonacci theo cách đệ quy là

F (n) = F (n-1) + F (n-2) với F (0) = 0 và F (1) = 1

Xác định rõ ràng điều này một cách đệ quy trong Python có thể được thực hiện như sau:

def rec_fib(n):
    '''inefficient recursive function as defined, returns Fibonacci number'''
    if n > 1:
        return rec_fib(n-1) + rec_fib(n-2)
    return n

Nhưng biểu diễn chính xác của định nghĩa toán học này cực kỳ kém hiệu quả đối với các số lớn hơn 30, bởi vì mỗi số được tính toán cũng phải tính cho mọi số bên dưới nó. Bạn có thể chứng minh mức độ chậm của nó bằng cách sử dụng như sau:

for i in range(40):
    print(i, rec_fib(i))

Ghi nhớ đệ quy cho hiệu quả

Nó có thể được ghi nhớ để cải thiện tốc độ (ví dụ này lợi dụng thực tế là một đối số từ khóa mặc định là cùng một đối tượng mỗi khi hàm được gọi, nhưng thông thường bạn sẽ không sử dụng đối số mặc định có thể thay đổi cho chính xác lý do này):

def mem_fib(n, _cache={}):
    '''efficiently memoized recursive function, returns a Fibonacci number'''
    if n in _cache:
        return _cache[n]
    elif n > 1:
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

Bạn sẽ thấy phiên bản ghi nhớ nhanh hơn nhiều và sẽ nhanh chóng vượt quá độ sâu đệ quy tối đa của bạn trước khi bạn kịp nghĩ đến việc dậy uống cà phê. Bạn có thể thấy nó nhanh hơn bao nhiêu bằng cách thực hiện điều này:

for i in range(40):
    print(i, mem_fib(i))

(Có vẻ như chúng ta chỉ có thể thực hiện các thao tác bên dưới, nhưng thực tế nó không cho phép chúng ta tận dụng bộ đệm, vì nó tự gọi trước khi setdefault được gọi.)

def mem_fib(n, _cache={}):
    '''don't do this'''
    if n > 1:  
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

Trình tạo định nghĩa đệ quy:

Khi tôi đang học Haskell, tôi đã bắt gặp cách triển khai này trong Haskell:

fib@(0:tfib) = 0:1: zipWith (+) fib tfib

Gần nhất tôi nghĩ rằng tôi có thể có được điều này trong Python tại thời điểm này là:

from itertools import tee

def fib():
    yield 0
    yield 1
    # tee required, else with two fib()'s algorithm becomes quadratic
    f, tf = tee(fib()) 
    next(tf)
    for a, b in zip(f, tf):
        yield a + b

Điều này chứng tỏ điều đó:

[f for _, f in zip(range(999), fib())]

Nó chỉ có thể đi đến giới hạn đệ quy. Thông thường, 1000, trong khi phiên bản Haskell có thể lên tới 100 triệu, mặc dù nó sử dụng tất cả 8 GB bộ nhớ máy tính xách tay của tôi để làm như vậy:

> length $ take 100000000 fib 
100000000

Sử dụng iterator để có được số thứ n Wikipedia

Một bình luận hỏi:

Câu hỏi cho hàm Fib () dựa trên iterator: nếu bạn muốn lấy số thứ n, ví dụ số sợi thứ 10 thì sao?

Tài liệu itertools có một công thức cho việc này:

from itertools import islice

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)

và bây giờ:

>>> nth(fib(), 10)
55

Về tùy chọn '' 'không làm điều này' '' cuối cùng, tôi không hiểu tại sao nó lại tự gọi mình trước khi setdefault. Không phải setdefault sẽ trả về giá trị nếu n là khóa hợp lệ? Doc nói "Nếu khóa nằm trong từ điển, hãy trả về giá trị của nó. Nếu không, hãy chèn khóa có giá trị mặc định và trả về mặc định. Mặc định mặc định là Không có." Tôi đang thiếu gì?
binithb

@binithb biểu thức bên trong setdefaultcuộc gọi được ước tính trước setdefault là.
Aaron Hall

23

Tại sao không chỉ đơn giản là làm như sau?

x = [1,1]
for i in range(2, 10):  
    x.append(x[-1] + x[-2]) 
print(', '.join(str(y) for y in x))

21

Ý tưởng đằng sau chuỗi Fibonacci được hiển thị trong mã Python sau:

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

Điều này có nghĩa là sợi là một chức năng có thể làm một trong ba điều. Nó định nghĩa sợi (1) == 1, sợi (0) == 0 và sợi (n) là:

sợi (n-1) + sợi (n-2)

Trong đó n là một số nguyên tùy ý. Điều này có nghĩa là ví dụ (2), mở rộng ra số học sau:

fib(2) = fib(1) + fib(0)
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(2) = 1 + 0
fib(2) = 1

Chúng ta có thể tính toán sợi (3) theo cách tương tự với số học được hiển thị bên dưới:

fib(3) = fib(2) + fib(1)
fib(2) = fib(1) + fib(0)
fib(2) = 1
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(3) = 1 + 1 + 0

Điều quan trọng cần nhận ra ở đây là không thể tính được xơ (3) nếu không tính toán xơ (2), được tính bằng cách biết các định nghĩa về xơ (1) và xơ (0). Có một chức năng gọi chính nó giống như chức năng Dailymotion được gọi là đệ quy và đó là một chủ đề quan trọng trong lập trình.

Điều này nghe có vẻ như một bài tập về nhà vì vậy tôi sẽ không làm phần bắt đầu / kết thúc cho bạn. Python là một ngôn ngữ biểu cảm tuyệt vời cho điều này mặc dù, vì vậy điều này sẽ có ý nghĩa nếu bạn hiểu toán học, và hy vọng sẽ dạy cho bạn về đệ quy. Chúc may mắn!

Chỉnh sửa: Một chỉ trích tiềm năng đối với mã của tôi là nó không sử dụng năng suất hàm Python siêu tiện dụng, điều này làm cho hàm xơ (n) ngắn hơn rất nhiều. Ví dụ của tôi là chung chung hơn một chút, vì không có nhiều ngôn ngữ bên ngoài Python thực sự có năng suất.


Đây không phải là một vấn đề bài tập về nhà nhưng wow cảm ơn bạn đã trả lời! Tôi hiểu những gì tôi cần làm nhưng bắt đầu và thực hiện là những gì tôi đang bị mắc kẹt bây giờ (đặc biệt là với việc thực hiện các giá trị đầu vào của người dùng). Bạn có thể cung cấp một số cái nhìn sâu sắc về điều này? Tôi liên tục nhận được một lỗi <hàm sợi tại 0x0141FAF0>.
SD.

Tôi hiểu rằng bạn đang rất cố gắng để thực hiện một chương trình có thể vượt quá khả năng hiện tại của bạn. Có tôi viết thêm mã sẽ không giúp bạn. Bạn nên cố gắng hack xung quanh với mã của tôi cho đến khi nó hoạt động và đọc thêm các hướng dẫn về Python. Khoảng trắng có thể là một vấn đề, nhưng tôi không biết lỗi đó.
James Thompson

Tôi hiểu. Có bất kỳ ý tưởng khác mà bạn nghĩ rằng tôi có thể bị mất? Tôi hiểu nếu bạn không thể giúp đỡ tuy nhiên. Tôi cảm ơn bạn đã dành thời gian của bạn.
SD.

Lỗi <hàm sợi tại 0x0141FAF0> của bạn có thể là kết quả của việc nói "sợi" (dùng để chỉ chính hàm) thay vì "sợi ()" sẽ gọi hàm. May mắn nhất.
Kiv

8
Hãy nhớ rằng phương pháp đệ quy ngây thơ này để tính toán các số Fibonacci có thể đi vào tràn ngăn xếp (không phải trang web) thực sự nhanh. Đối với mục đích thực tế, tạo lặp đi lặp lại hoặc sử dụng một số loại ghi nhớ hoặc một cái gì đó.
David Thornley

12

Thời gian phức tạp:

Tính năng lưu vào bộ đệm giúp giảm cách tính toán chuỗi Fibonacci thông thường từ O (2 ^ n) sang O (n) bằng cách loại bỏ các lần lặp lại trong cây đệ quy của chuỗi Fibonacci:

nhập mô tả hình ảnh ở đây

Mã số:

import sys

table = [0]*1000

def FastFib(n):
    if n<=1:
        return n
    else:
        if(table[n-1]==0):
            table[n-1] = FastFib(n-1)
        if(table[n-2]==0):
            table[n-2] = FastFib(n-2)
        table[n] = table[n-1] + table[n-2]
        return table[n]

def main():
    print('Enter a number : ')
    num = int(sys.stdin.readline())
    print(FastFib(num))

if __name__=='__main__':
    main()

9

Điều này khá hiệu quả, sử dụng các phép toán số học cơ bản O (log n).

def fib(n):
    return pow(2 << n, n + 1, (4 << 2*n) - (2 << n) - 1) % (2 << n)

Công cụ này sử dụng các phép toán số học cơ bản O (1), nhưng kích thước của các kết quả trung gian là lớn và do đó không hiệu quả.

def fib(n):
    return (4 << n*(3+n)) // ((4 << 2*n) - (2 << n) - 1) & ((2 << n) - 1)

Cái này tính X ^ n trong vòng đa thức Z [X] / (X ^ 2 - X - 1) bằng cách sử dụng lũy ​​thừa bằng cách bình phương. Kết quả của phép tính đó là Fib đa thức (n) X + Fib (n-1), từ đó có thể đọc được số Fibonacci thứ n.

Một lần nữa, điều này sử dụng các phép toán số học O (log n) và rất hiệu quả.

def mul(a, b):
        return a[0]*b[1]+a[1]*b[0]+a[0]*b[0], a[0]*b[0]+a[1]*b[1]

def fib(n):
        x, r = (1, 0), (0, 1)
        while n:
                if n & 1: r = mul(r, x)
                x = mul(x, x)
                n >>= 1
        return r[0]

1
Các kỹ thuật đầu tiên và thứ ba là tốt. Kỹ thuật thứ hai tắt 1; nó thực sự cần n -= 1phải hoạt động chính xác, và nó cũng không hoạt động n = 0. Trong mọi trường hợp, nó thực sự sẽ giúp tôi nếu nhiều bối cảnh được thêm vào để giải thích cách thức chúng hoạt động, đặc biệt là kỹ thuật đầu tiên. Tôi thấy bạn có một bài đăng tại paulhankin.github.io/Fiborie
Acumenus

6

Mã Pythonical để in chuỗi Fibonacci:

a,b=1,1
while True:
  print a,
  a,b=b,a+b       # Could also use b=a+b;a=b-a

Đối với vấn đề "In số Fibonacci đầu tiên dài hơn 1000 chữ số":

a,b=1,1
i=1
while len(str(a))<=1000:
  i=i+1
  a,b=b,a+b

print i,len(str(a)),a

4

Chúng ta biết rằng

nhập mô tả hình ảnh ở đây

Và sức mạnh thứ n của ma trận đó mang lại cho chúng ta:

nhập mô tả hình ảnh ở đây

Vì vậy, chúng ta có thể thực hiện một hàm chỉ đơn giản là tính toán sức mạnh của ma trận đó với công suất -1.

như tất cả chúng ta biết sức mạnh a ^ n bằng

nhập mô tả hình ảnh ở đây

Vì vậy, cuối cùng, chức năng Dailymotion sẽ là O (n) ... không có gì thực sự khác với việc thực hiện dễ dàng hơn nếu thực tế là chúng ta cũng biết điều đó x^n * x^n = x^2nvà việc đánh giá x^ncó thể được thực hiện với độ phức tạp O (log n )

Đây là cách thực hiện của tôi bằng cách sử dụng ngôn ngữ lập trình nhanh chóng:

struct Mat {
    var m00: Int
    var m01: Int
    var m10: Int
    var m11: Int
}

func pow(m: Mat, n: Int) -> Mat {
    guard n > 1 else { return m }
    let temp = pow(m: m, n: n/2)

    var result = matMultiply(a: temp, b: temp)
    if n%2 != 0 {
        result = matMultiply(a: result, b: Mat(m00: 1, m01: 1, m10: 1, m11: 0))
    }
    return result
}

func matMultiply(a: Mat, b: Mat) -> Mat {
    let m00 = a.m00 * b.m00 + a.m01 * b.m10
    let m01 = a.m00 * b.m01 + a.m01 * b.m11
    let m10 = a.m10 * b.m00 + a.m11 * b.m10
    let m11 = a.m10 * b.m01 + a.m11 * b.m11

    return Mat(m00: m00, m01: m01, m10: m10, m11: m11)
}

func fibonacciFast(n: Int) -> Int {

    guard n > 0 else { return 0 }
    let m = Mat(m00: 1, m01: 1, m10: 1, m11: 0)

    return pow(m: m, n: n-1).m00
}

Điều này có độ phức tạp O (log n). Chúng tôi tính toán oì lực của Q với số mũ n-1 và sau đó chúng tôi lấy phần tử m00 là Fn + 1 với số mũ lũy thừa n-1 chính xác là số Fib-n thứ n mà chúng tôi muốn.

Khi bạn có chức năng MySpace nhanh, bạn có thể lặp lại từ số bắt đầu và số kết thúc để có được một phần của chuỗi Fibonacci mà bạn quan tâm.

let sequence = (start...end).map(fibonacciFast)

tất nhiên trước tiên hãy thực hiện một số kiểm tra khi bắt đầu và kết thúc để đảm bảo chúng có thể tạo thành một phạm vi hợp lệ.

Tôi biết câu hỏi đã 8 tuổi, nhưng dù sao tôi cũng rất vui khi trả lời. :)


3

Chuỗi Fibonacci là : 1, 1, 2, 3, 5, 8, ....

Đó là f(1) = 1, f(2) = 1, f(3) = 2, ..., f(n) = f(n-1) + f(n-2).

Triển khai yêu thích của tôi (đơn giản nhất nhưng vẫn đạt được tốc độ ánh sáng so với các triển khai khác) là:

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

Kiểm tra

>>> [fibonacci(i) for i in range(1, 10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34]

Thời gian

>>> %%time
>>> fibonacci(100**3)
CPU times: user 9.65 s, sys: 9.44 ms, total: 9.66 s
Wall time: 9.66 s

Chỉnh sửa: một ví dụ trực quan cho việc thực hiện này.


3

sử dụng đệ quy:

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
x=input('which fibonnaci do you want?')
print fib(x)

2

Một cách khác để làm điều đó:

a,n=[0,1],10
map(lambda i: reduce(lambda x,y: a.append(x+y),a[-2:]),range(n-2))

Gán danh sách cho 'a', gán số nguyên cho 'n' Map và rút gọn là 2 trong ba hàm mạnh nhất trong python. Ở đây bản đồ được sử dụng chỉ để lặp lại 'n-2' lần. a [-2:] sẽ nhận được hai phần tử cuối cùng của một mảng. a.append (x + y) sẽ thêm hai phần tử cuối cùng và sẽ nối vào mảng


1

Tất cả đều có vẻ phức tạp hơn một chút so với mức cần thiết. Mã của tôi rất đơn giản và nhanh chóng:

def fibonacci(x):

    List = []
    f = 1
    List.append(f)
    List.append(f) #because the fibonacci sequence has two 1's at first
    while f<=x:
        f = List[-1] + List[-2]   #says that f = the sum of the last two f's in the series
        List.append(f)
    else:
        List.remove(List[-1])  #because the code lists the fibonacci number one past x. Not necessary, but defines the code better
        for i in range(0, len(List)):
        print List[i]  #prints it in series form instead of list form. Also not necessary

2
Lập trình động FTW! Dailymotion (1000000000000000000000000000000000000000000000000000000000000000000000000000000) trả lời gần như ngay lập tức
Hans

6
Bằng cách nào đó tôi nghi ngờ nó.
Lanaru 18/03/2015

Điều gì về việc bắt đầu danh sách là [0, 1] (tức là List.append (0); List.append (1)) để tránh lệnh remove sau lệnh khác? ... Và số lượng Wikipedia nên được lập chỉ mục tốt hơn vì MySpace (10) trả về các số Wikipedia dưới 10, chứ không phải số thứ 10.
SeF

1

OK .. sau khi mệt mỏi với việc tham khảo tất cả các câu trả lời dài dòng, bây giờ hãy tìm cách sắp xếp dưới đây & ngọt ngào, khá đơn giản để thực hiện Fibonacci trong python. Bạn có thể cải thiện nó theo cách bạn muốn bằng cách nhận một đối số hoặc nhận người dùng nhập dữ liệu hoặc thay đổi các giới hạn từ 10000. Khi bạn cần

def fibonacci():
    start = 0 
    i = 1 
    lt = []
    lt.append(start)
    while start < 10000:
        start += i
        lt.append(start)
        i = sum(lt[-2:])
        lt.append(i)
    print "The Fibonaccii series: ", lt

Cách tiếp cận này cũng thực hiện tốt. Tìm các phân tích chạy bên dưới

In [10]: %timeit fibonacci
10000000 loops, best of 3: 26.3 ns per loop

1

đây là một cải tiến cho câu trả lời của mathew henry:

def fib(n):
    a = 0
    b = 1
    for i in range(1,n+1):
            c = a + b
            print b
            a = b
            b = c

mã nên in b thay vì in c

sản lượng: 1,1,2,3,5 ....


1

Sử dụng cho vòng lặp và chỉ in kết quả

def fib(n:'upto n number')->int:
    if n==0:
        return 0
    elif n==1:
        return 1
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
    return b

Kết quả

>>>fib(50)
12586269025
>>>>
>>> fib(100)
354224848179261915075
>>> 

In listchứa tất cả các số

def fib(n:'upto n number')->int:
    l=[0,1]
    if n==0:
        return l[0]
    elif n==1:
        return l
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
        l.append(b)
    return l

Kết quả

>>> fib(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1
import time
start_time = time.time()



#recursive solution
def fib(x, y, upperLimit):
    return [x] + fib(y, (x+y), upperLimit) if x < upperLimit else [x]

#To test :

print(fib(0,1,40000000000000))
print("run time: " + str(time.time() - start_time))

Các kết quả

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368 , 75025, 75025, 75025, 75025, 75025, 725 b:: 10 năm 10 :::: 10: 10

thời gian chạy: 0,04298138618469238


1

Có một phương pháp rất dễ để nhận ra điều đó!

bạn có thể chạy mã này trực tuyến một cách tự do bằng cách sử dụng http://www.learnpython.org/

# Set the variable brian on line 3!

def fib(n):
"""This is documentation string for function. It'll be available by fib.__doc__()
Return a list containing the Fibonacci series up to n."""
result = []
a = 0
b = 1
while a < n:
    result.append(a)  # 0 1 1 2 3 5  8  (13) break
    tmp_var = b       # 1 1 2 3 5 8  13
    b = a + b         # 1 2 3 5 8 13 21
    a = tmp_var       # 1 1 2 3 5 8  13
    # print(a)
return result

print(fib(10))
# result should be this: [0, 1, 1, 2, 3, 5, 8]

một cách dễ dàng để nhận ra chuỗi Fibonacci chỉ bằng cách sử dụng iterator, mà không có bất kỳ cấu trúc dữ liệu đệ quy phức tạp nào!
xgqfrms

1

Nó có thể được thực hiện theo cách sau.

n = 0

số = [0]

cho i trong phạm vi (0,11):
    in n,
    số.append (n)
    trước = số [-2]
    nếu n == 0:
        n = 1
    khác:
        n = n + trước

1

Để giải trí, trong Python 3.8+, bạn có thể sử dụng biểu thức gán (hay còn gọi là toán tử hải mã) để hiểu danh sách, ví dụ:

>>> a, b = 0, 1
>>> [a, b] + [b := a + (a := b) for _ in range(8)]  # first 10 Fibonacci numbers
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Một biểu thức gán cho phép bạn gán một giá trị cho một biến trả về nó trong cùng một biểu thức. Do đó, biểu thức

b := a + (a := b)

tương đương với thực thi

a, b = b, a + b

và trả về giá trị của b.


0

15 phút trong một hướng dẫn mà tôi đã sử dụng khi học Python, nó đã yêu cầu người đọc viết một chương trình sẽ tính toán một chuỗi Fibonacci từ 3 số đầu vào (số Fibonacci đầu tiên, số thứ hai và số để dừng chuỗi). Hướng dẫn chỉ bao gồm các biến, if / thens và các vòng lặp cho đến thời điểm đó. Không có chức năng nào. Tôi đã đưa ra mã sau đây:

sum = 0
endingnumber = 1                

print "\n.:Fibonacci sequence:.\n"

firstnumber = input("Enter the first number: ")
secondnumber = input("Enter the second number: ")
endingnumber = input("Enter the number to stop at: ")

if secondnumber < firstnumber:

    print "\nSecond number must be bigger than the first number!!!\n"

else:

while sum <= endingnumber:

    print firstnumber

    if secondnumber > endingnumber:

        break

    else:

        print secondnumber
        sum = firstnumber + secondnumber
        firstnumber = sum
        secondnumber = secondnumber + sum

Như bạn có thể thấy, nó thực sự không hiệu quả, nhưng nó KHÔNG hoạt động.


0
def fib():
    a,b = 1,1
    num=eval(input("Please input what Fib number you want to be calculated: "))
    num_int=int(num-2)
    for i in range (num_int):
        a,b=b,a+b
    print(b)

3
eval(input())không cần thiết ở đây; Tôi nghĩ int(input())trong trường hợp là tốt hơn.
GingerPlusPlus

0

Chỉ cần xem qua http://projecteuler.net/probols=2, đây là sự đảm nhận của tôi

# Even Fibonacci numbers
# Problem 2

def get_fibonacci(size):
    numbers = [1,2]
    while size > len(numbers):
        next_fibonacci = numbers[-1]+numbers[-2]
        numbers.append(next_fibonacci)

    print numbers

get_fibonacci(20)

0
def fib(x, y, n):
    if n < 1: 
        return x, y, n
    else: 
        return fib(y, x + y, n - 1)

print fib(0, 1, 4)
(3, 5, 0)

#
def fib(x, y, n):
    if n > 1:
        for item in fib(y, x + y, n - 1):
            yield item
    yield x, y, n

f = fib(0, 1, 12)
f.next()
(89, 144, 1)
f.next()[0]
55

0

Có thể điều này sẽ giúp

def fibo(n):
    result = []
    a, b = 0, 1
    while b < n:
            result.append(b)
            a, b = b, b + a
    return result

0

dựa trên chuỗi trò chơi cổ điển và chỉ vì lợi ích của một lớp lót

nếu bạn chỉ cần số chỉ mục, bạn có thể sử dụng mức giảm (ngay cả khi giảm nó không phù hợp nhất cho việc này thì đó có thể là một bài tập tốt)

def fibonacci(index):
    return reduce(lambda r,v: r.append(r[-1]+r[-2]) or (r.pop(0) and 0) or r , xrange(index), [0, 1])[1]

và để có được mảng hoàn chỉnh, chỉ cần loại bỏ hoặc (r.pop (0) và 0)

reduce(lambda r,v: r.append(r[-1]+r[-2]) or r , xrange(last_index), [0, 1])

0

Cái này thì sao? Tôi đoán nó không lạ mắt như các đề xuất khác bởi vì nó yêu cầu thông số ban đầu của kết quả trước đó để tạo ra kết quả mong đợi, nhưng tôi cảm thấy là một tùy chọn rất dễ đọc, tức là, tất cả những gì nó làm là cung cấp kết quả và kết quả trước đó cho đệ quy.

#count the number of recursions
num_rec = 0

def fibonacci(num, prev, num_rec, cycles):

    num_rec = num_rec + 1

    if num == 0 and prev == 0:
        result  = 0;
        num = 1;
    else:
        result = num + prev

    print(result)

    if num_rec == cycles:
        print("done")
    else:
        fibonacci(result, num, num_rec, cycles)

#Run the fibonacci function 10 times
fibonacci(0, 0, num_rec, 10)

Đây là đầu ra:

0
1
1
2
3
5
8
13
21
34
done

0

Về cơ bản được dịch từ Ruby:

def fib(n):
    a = 0
    b = 1
    for i in range(1,n+1):
            c = a + b
            print c
            a = b
            b = c

...


0
def fib(lowerbound, upperbound):
    x = 0
    y = 1
    while x <= upperbound:
        if (x >= lowerbound):
            yield x
        x, y = y, x + y

startNumber = 10
endNumber = 100
for fib_sequence in fib(startNumber, endNumber):
    print "And the next number is... %d!" % fib_sequence

0

Một lời giải thích chi tiết hơn về cách thức Ghi nhớ hoạt động cho chuỗi Fibonacci.

# Fibonacci sequence Memoization

fib_cache = {0:0, 1:1}

def fibonacci(n):
    if n < 0:
        return -1
    if fib_cache.has_key(n):
        print "Fibonacci sequence for %d = %d cached" % (n, fib_cache[n])
        return fib_cache[n]
    else:
        fib_cache[n] = fibonacci(n - 1) + fibonacci(n - 2)
    return fib_cache[n]

if __name__ == "__main__":
    print fibonacci(6)
    print fib_cache
    # fibonacci(7) reuses fibonacci(6) and fibonacci(5)
    print fibonacci(7)
    print fib_cache

0

Tôi đã cố gắng tránh một hàm đệ quy để giải quyết vấn đề này, vì vậy tôi đã thực hiện một cách tiếp cận lặp lại. Ban đầu tôi đã thực hiện một chức năng đệ quy ghi nhớ nhưng vẫn đạt độ sâu đệ quy tối đa. Tôi cũng có các mục tiêu bộ nhớ nghiêm ngặt vì vậy bạn sẽ thấy tôi giữ mảng nhỏ nhất có thể trong quá trình lặp chỉ giữ 2-3 giá trị trong mảng bất cứ lúc nào.

def fib(n):
    fibs = [1, 1] # my starting array
    for f in range(2, n):
        fibs.append(fibs[-1] + fibs[-2]) # appending the new fib number
        del fibs[0] # removing the oldest number
    return fibs[-1] # returning the newest fib

print(fib(6000000))

Lấy số thứ 6 triệu của Wikipedia mất khoảng 282 giây trên máy của tôi trong khi 600k Dailymotion chỉ mất 2,8 giây. Tôi đã không thể có được số lượng lớn như vậy với chức năng đệ quy, thậm chí là một số ghi nhớ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.