How to write the Fibonacci Sequence?

前端 未结 30 2330
醉酒成梦
醉酒成梦 2020-11-22 00:32

I had originally coded the program wrongly. Instead of returning the Fibonacci numbers between a range (ie. startNumber 1, endNumber 20 should = only those numbers between 1

30条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 01:10

    We know that

    And that The n-th power of that matrix gives us:

    So we can implement a function that simply computes the power of that matrix to the n-th -1 power.

    as all we know the power a^n is equal to

    So at the end the fibonacci function would be O( n )... nothing really different than an easier implementation if it wasn't for the fact that we also know that x^n * x^n = x^2n and the evaluation of x^n can therefore be done with complexity O( log n )

    Here is my fibonacci implementation using swift programming language:

    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
    }
    

    This has complexity O( log n ). We compute the oìpower of Q with exponent n-1 and then we take the element m00 which is Fn+1 that at the power exponent n-1 is exactly the n-th Fibonacci number we wanted.

    Once you have the fast fibonacci function you can iterate from start number and end number to get the part of the Fibonacci sequence you are interested in.

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

    of course first perform some check on start and end to make sure they can form a valid range.

    I know the question is 8 years old, but I had fun answering anyway. :)

提交回复
热议问题