Có thể tìm thấy số hạng thứ n của chuỗi Fibonacci bằng cách sử dụng một vòng lặp dứt khoát không?


7

Tôi đang sử dụng cuốn sách Giới thiệu về Khoa học máy tính của John Zelle và ở cuối Chương 3 (Tính toán với các số), tôi được yêu cầu tìm thuật ngữ thứ n của chuỗi Fibonacci có lẽ sử dụng vòng lặp dứt khoát, vì không có quyết định nào khác cấu trúc đã được giới thiệu chưa.

Điều này có thể không? Tôi đã thử mọi thứ tôi có thể nghĩ ra.

** Tôi biết làm thế nào để giải quyết nó bằng cách sử dụng câu lệnh if và như vậy. Nhưng cuốn sách chưa đề cập đến các cấu trúc quyết định, nhưng nó yêu cầu tôi tìm thuật ngữ thứ n (do người dùng đưa ra). Vì vậy, tôi chỉ có thể đoán biết cách thực hiện điều này bằng cách sử dụng các vòng lặp "cho" vì đây là tất cả những gì đã được bảo hiểm cho đến nay


1
"Definitive for loop" nghĩa là gì?
Keith Thompson

Về cơ bản là một vòng lặp được tính. Ví dụ: tôi lấy thuật ngữ thứ n làm đầu vào và nói cho i trong phạm vi (đầu vào):
qzxt

Tôi có thể xóa các ifcâu lệnh bằng cách di chuyển các biểu thức có điều kiện sang các vòng lặp nhưng đó chỉ là một hack hoàn toàn vô dụng, IMHO.
toniedzwiedz

Vì vậy, tôi không điên, và thực sự không có điều gì để làm điều này mà không có điều kiện?
qzxt

@qzxt không nếu bạn muốn bắt đầu vào không hợp lệ, không.
toniedzwiedz

Câu trả lời:


11

Nếu nó chỉ là chương thứ ba, tôi nghi ngờ các tác giả đã trình bày chương trình động, nhưng tôi sẽ minh họa những gì đang xảy ra khi một vòng lặp for được sử dụng để tính toán nth Số Fibonacci, Fn.

Nhớ lại định nghĩa,

Fn={0n=01n=1Fn1+Fn2otherwise

Chúng ta có thể tính toán một cách ngây thơ điều này bằng cách sử dụng hàm đệ quy được định nghĩa trong Python là,

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

Tuy nhiên, bằng cách tính toán lại cùng một vấn đề phụ nhiều lần, hàm này đòi hỏi thời gian theo cấp số nhân để tính toán (minh họa bên dưới)! sợi quang

Có một sửa chữa, mặc dù. Chúng ta có thể sử dụng lập trình động để thực hiện đệ quy "thông minh hơn" và giữ kết quả trước đó. Theo cách này, chúng ta không cần phải tính toán lạiFi. Hàm gọi "cây" của chúng ta sẽ thu gọn vào một danh sách và sẽ tính toánFn từ dưới lên". sợi2

def fib2(n):
    if n < 2:
        return n
    else:
        if not results[n]:
            results[n] = fib2(n - 1) + fib2(n - 2)
        return results[n]

Bây giờ chúng tôi có O(n) thuật toán thời gian để tính toán Fn, nhưng nếu bạn chú ý, chúng tôi yêu cầu O(n) không gian bổ sung (một điểm trong mảng cho mỗi Fi). Điều này có thể được cắt giảm đểO(1) không gian bổ sung vì mỗi Fi chỉ yêu cầu hai số khác, cụ thể là Fi1Fi2.

def fib3(n):
    if n < 2:
        return n
    f_0 = 0
    f_1 = 1
    f_n = 0
    for _ in range(n - 1):
        f_n = f_0 + f_1
        f_0 = f_1
        f_1 = f_n


    return f_n

2
Wow, câu trả lời tuyệt vời! Lưu ý rằng việc đưa điều này thành một hình thức tương thích với đệ quy nguyên thủy - nghĩa là, đếm ngược trong các định nghĩa phổ biến - rất dễ dàng bằng cách sử dụngnibên trong vòng lặp (đếm ngược).
Raphael

10

Nếu bạn chỉ phải sử dụng một vòng lặp for lặp đi lặp lại cho đến khi nó tìm thấy số Fibonacci thứ n, bạn có thể sử dụng một cái gì đó như thế này:

int fib(int n)
{
    int p = 0;
    int c = 1;
    int r = 0; // The result is initialized to 0 (undefined). 
    for (int i = 0; i < n; i++)
    {
        r = p + c; // Produce next number in the sequence.
        p = c;     // Save previous number.
        c = r;     // Save current number.
    }

    return r;
}

GHI CHÚ

Trong giải pháp ở trên, tôi giả sử rằng chuỗi Fibonacci là 1 1 2 3 5 8 13 ... và n có phạm vi 1, 2, 3, ... Vì theo các giả định này, không có số Fibonacci cho n <1 , hàm trả về 0 cho n <1 để chỉ ra rằng tham số đầu vào nằm ngoài phạm vi (xem các đề xuất của Tom trong các bình luận bên dưới).


Đầu ra cho 0 nên là 0, nếu không, một câu trả lời hay, đơn giản và súc tích.
toniedzwiedz

Nó phụ thuộc vào cách bạn đếm, thực ra nên xác định số nguyên cho n <1. Hoặc bạn có nghĩa là 0 đại diện cho không xác định, và do đó, sợi (n) sẽ trả về 0 cho tất cả n <1?
Giorgio

Đó là sự thật, nó phụ thuộc. Nếu chúng ta bao gồm 0, đầu ra phải là 0. Nếu chúng ta loại trừ nó, hàm sẽ trả về một giá trị đặc biệt để chỉ ra đầu vào không hợp lệ, điều này cũng được thực hiện cho các số âm ... nhưng OP không chấp nhận các biểu thức điều kiện, ít ném ngoại lệ hơn nên tôi đoán nó ổn theo cách của nó.
toniedzwiedz

2
@Giorgio Về mặt toán học, chuỗi Fibonacci được xác định hoàn toàn tốt cho n<0; không có gì ngăn cản bạn chạy trình tự ngược , đảo ngượcfn+1=fn+fn1 để có được fn1=fn+1fn - hoặc, xác định gn=fn, gn+1=gn1gn.
Steven Stadnicki
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.