Swift學習—— 求Fibonacci數列

參考自:http://www.cnblogs.com/python27/archive/2011/11/25/2261980.html

題目:定義Fibonacci數列如下:

分析1:看到斐波那契數列幾乎所有的程序員在第一時間的反應都是遞歸,沒錯了,作爲和漢諾塔一樣的經典遞歸問題,我們幾乎毫不猶豫就可以寫出如下的代碼:

func fibonacci_1(index:Int)->Int{
    if index == 0{
        return 0
    }
    else if index == 1{
        return 1
    }
    else
    {
        return fibonacci_1(index-1)+fibonacci_1(index-2)
    }
}

分析2:既然上面算法的主要缺點是要重複的計算很多不必要的數值,那麼我們的想法是不計算那些重複的值,我們考慮對於任意一個N值,我們從第一項開始,不斷的累積下去,這樣就可以避免重複計算。由於是從第一項逐次求解,所以該算法的時間複雜度爲O(n)。代碼如下:

func fibonacci_2(index:Int)->Int{
    if index == 0{
        return 0
    }
    else if index == 1{
        return 1
    }
    else
    {
        var firstNum:Int = 0
        var secondNum:Int = 1
        var count = 1
        var fib = 0
        while count < index
        {
            fib = firstNum + secondNum
            firstNum = secondNum
            secondNum = fib
            ++count
        }
        return fib
    }
}

分析3:最後介紹一種效率最高的算法O(logn),首先我們有下面的數學公式:

我們可以用數學歸納法證明如下:

Step1: n=2

Step2:設n=k時,公式成立,則有:

等式兩邊同乘以[1,1;1,0]矩陣可得:

=右,這正是n=k+1時的形式,即當n=k+1時等式成立。

Step1Step2可知,該數學公式成立。

由此可以知道該問題轉化爲計算右邊矩陣的n-1冪問題。

我們利用分治的算法思想可以考慮如下求解一個數A的冪。

實現這種算法需要定義矩陣,以及矩陣的有關運算,具體代碼如下:

//定義一個矩陣結構體
struct Matrix2by2 {
    var m00:Int
    var m01:Int
    var m10:Int
    var m11:Int
    init(m_00:Int, m_01:Int, m_10:Int, m_11:Int){
        self.m00 = m_00
        self.m01 = m_01
        self.m10 = m_10
        self.m11 = m_11
    }
    
}

//定義2X2矩陣的乘法運算
func matrixMultiply(matrix1:Matrix2by2, matrix2:Matrix2by2)->Matrix2by2{
    var matrix12:Matrix2by2 = Matrix2by2(m_00: 1, m_01: 1, m_10: 1, m_11: 0)
    matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10
    matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11
    matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10
    matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11
    return matrix12
}

//定義2X2矩陣的冪運算
func matrixPower(n:Int)->Matrix2by2{
    var matrix:Matrix2by2 = Matrix2by2(m_00: 1, m_01: 1, m_10: 1, m_11: 0)
    if n == 1{
        matrix = Matrix2by2(m_00: 1, m_01: 1, m_10: 1, m_11: 0)
    }
    else if n % 2 == 0{
        matrix = matrixPower(n/2)
        matrix = matrixMultiply(matrix, matrix)
    }
    else if n % 2 == 1{
        matrix = matrixPower((n-1) / 2)
        matrix = matrixMultiply(matrix, matrix)
        matrix = matrixMultiply(matrix, Matrix2by2(m_00: 1, m_01: 1, m_10: 1, m_11: 0))
    }
    return matrix
}

func fibonacci_3(index:Int)->Int{
    if index == 0{
        return 0
    }
    else if index == 1{
        return 1
    }
    else{
        var fibMatrix:Matrix2by2 = matrixPower(index-1)
        return fibMatrix.m00
    }
}

發佈了34 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章