简体   繁体   中英

Huge Fibonacci Number

I just started learning algorithms and I am stuck with the problem of finding a huge Fibonacci number. My example input is 5949. The output should be calculated in less than 5 seconds.

Here is my attempt:

def calc_fib(n):
    if n < 0:
       print ("Error. Bad input")
    elif n <= 2:
        return 1
    else:
        F = []
    for i in range (2,n):
        F[i] = F[i-1]+F[i-2]
    return F[n]

n = int(input())
print(calc_fib(n))

But I get an error on line with arrays: IndexError: list index out of range

you created a empty list and are indexing position in the list which do not exist. Also use append as you are adding new elements

def calc_fib(n):
    if n < 0:
       print ("Error. Bad input")
    elif n <= 2:
        return 1
    else:
        F = [0,1] # <- change
    for i in range (2,n):
        F.append(F[i-1]+F[i-2]) # <- change
    return F[n]

n = int(input())
print(calc_fib(n))

You need to initialize the first two elements of your array: when i=2 , the line F[i]=F[i-1]+F[i-2] is really F[2]=F[1]+F[0] . But F[1] and F[0] don't exist: the array is empty!

As others have mentioned your error is due to attempting to access elements in the list that don't exist. A fresh Python list created using [] has no elements, you have to add elements to it before you can safely index into it.

As I mentioned in my comment you don't need to create a list here, unless you want to keep a table of Fibonacci numbers that can be accessed randomly.

To calculate single Fibonacci numbers Ibrahim's matrix multiplication algorithm is very fast, but it's not really necessary for calculating F(5949). A simple for loop can do that in less than 0.06 seconds on my old 2GHz machine.

from __future__ import print_function

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

# Test
for i in range(6):
    print(i, fib(i))    

output

0 0
1 1
2 1
3 2
4 3
5 5

If you are doing this on Python 2 replace range in fib by xrange to save memory.

You're getting an IndexError because you create an empty array, and in the next step you try to access its last two elements. You must initialize it with (at least) two elements.

There are already some answers here explaining what's wrong with your approach. However, if you're looking for an alternative idea, here's a really fast approach to find fibonacci numbers. It uses matrix multiplication and completes in O(log N) time. Using this approach, you can find Fibonacci of 5949 in milliseconds.

def matrix_mul(A, B):
    return ([A[0][0] * B[0][0] + A[0][1] * B[1][0],
         A[0][0] * B[0][1] + A[0][1] * B[1][1]],
        [A[1][0] * B[0][0] + A[1][1] * B[1][0],
        A[1][0] * B[0][1] + A[1][1] * B[1][1]])

def matrix_exp(A, e):
    if not e:
        return [[1,0],[0,1]]
    elif e % 2:
        return matrix_mul(A, matrix_exp(A, e-1))
    else:
        sq= matrix_exp(A, e//2)
        return matrix_mul(sq, sq)

def fibo(n):
    M = [[1,1],[1,0]]
    return matrix_exp(M, n)[0][0]

Read this for understanding why this works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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