1. 程式人生 > >c語言 寫一個函式,輸入n,求斐波拉契數列的第n項(5種方法,層層優化)

c語言 寫一個函式,輸入n,求斐波拉契數列的第n項(5種方法,層層優化)

               

寫一個函式,輸入n,求斐波拉契數列的第n項。

斐波拉契數列1,1,2,3,5,8...當n大於等於3時,後一項為前面兩項之和。

解:方法1:斐波拉契數列的函式定義角度程式設計

#include<stdio.h>


int fibonacci(int n)

{

 int num1=1, num2=1, num3=0,i;

 

if (n <= 2)

 {

  printf("斐波拉契數列的第%d項為:%d\n",n,num1);

 }

 else

 {

  for (i = 2; i < n; i++)

  {

   num3 = num1 + num2;

   num1 = num2;

   num2 = num3;

  }

  

printf("斐波拉契數列的第%d項為:%d\n", n, num3);

 }

 return 0;

}


int main()

{

 int num=0;

 printf("請輸入一個正整數:");

 scanf("%d", &num);

 fibonacci(num);

 return 0;

}

結果:

請輸入一個正整數:3

斐波拉契數列的第3項為:2

請按任意鍵繼續. . .

方法2:遞迴呼叫,很明顯優化了程式碼量

#include<stdio.h>


int fibonacci(int n)

{

 if (n <= 0)

 {

  return 0;

 }

 if (n == 1)

 {

  return 1;

 }

 return fibonacci(n-1)+ fibonacci(n - 2);

}


int main()

{

 int num = 0,ret=0;

 printf("請輸入一個正整數:");

 scanf("%d", &num);

 ret=fibonacci(num);

 printf("斐波拉契數列的第%d項為:%d\n", num,ret);

 return 0;

}

結果:

請輸入一個正整數:4

斐波拉契數列的第4項為:3

請按任意鍵繼續. . .

方法3提高遞迴的效率,把已經求得的中間項儲存起來,就不用再重複進行計算了;其本質相當於方法一的思想

#include<stdio.h>


int fibonacci(int n)

{

 int num1 = 1, num2 = 1, num3 = 0, i=0;

 if (n <= 2)

 {

  return num1;

 }

    for (i = 2; i < n; i++)

 {

  num3 = num1 + num2;

  num1 = num2;

  num2 = num3;

 }

 return num3;

}


int main()

{

 int num = 0,ret=0;

 printf("請輸入一個正整數:");

 scanf("%d", &num);

 ret=fibonacci(num);

 printf("斐波拉契數列的第%d項為:%d\n", num,ret);

 return 0;

}

結果:

請輸入一個正整數:3

斐波拉契數列的第3項為:2

請按任意鍵繼續. . .

方法4:直接運用數學公式法:f(n)={[(1+5^0.5)/2]^n - [(1-5^0.5)/2]^n}/(5^0.5)

#include<stdio.h>

#include<math.h>


int fibonacci(int n)

{

 return (pow((1+sqrt(5.0))/2,n)- pow((1 - sqrt(5.0)) / 2, n))/ sqrt(5.0);

}


int main()

{

 int num = 0, ret = 0;

 printf("請輸入一個正整數:");

 scanf("%d", &num);

 ret = fibonacci(num);

 printf("斐波拉契數列的第%d項為:%d\n", num, ret);

 return 0;

}

結果:

請輸入一個正整數:4

斐波拉契數列的第4項為:3

請按任意鍵繼續. . .

方法5生僻的數學公式法

 f(n)   f(n-1)  =    1     1

[              ]   [          ]^(n-1)

 f(n-1) f(n-2)       1     0

該公式可用數學歸納法進行證明,在矩陣乘法的變換證明過程中,要注意運用斐波拉契數列的性質:後一項為前面兩項之和;該數學公式,應用矩陣的乘法,時間效率雖然低,但不夠實用,原始碼太過繁瑣,提供如下程式碼僅供參考

#include <cassert>


struct Matrix2By2

{

 Matrix2By2

  (

   long long m00 = 0,

   long long m01 = 0,

   long long m10 = 0,

   long long m11 = 0

   )

  :m_00(m00), m_01(m01), m_10(m10), m_11(m11)

 {

 }


 long long m_00;

 long long m_01;

 long long m_10;

 long long m_11;

};


Matrix2By2 MatrixMultiply

(

 const Matrix2By2& matrix1,

 const Matrix2By2& matrix2

 )

{

 return Matrix2By2(

  matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,

  matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,

  matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,

  matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);

}


Matrix2By2 MatrixPower(unsigned int n)

{

 assert(n > 0);


 Matrix2By2 matrix;

 if (n == 1)

 {

  matrix = Matrix2By2(1, 1, 1, 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(1, 1, 1, 0));

 }


 return matrix;

}


long long Fibonacci_Solution3(unsigned int n)

{

 int result[2] = { 0, 1 };

 if (n < 2)

  return result[n];


 Matrix2By2 PowerNMinus2 = MatrixPower(n - 1);

 return PowerNMinus2.m_00;

}


// ====================測試程式碼====================

void Test(int n, int expected)

{

 if (Fibonacci_Solution1(n) == expected)

  printf("Test for %d in solution1 passed.\n", n);

 else

  printf("Test for %d in solution1 failed.\n", n);


 if (Fibonacci_Solution2(n) == expected)

  printf("Test for %d in solution2 passed.\n", n);

 else

  printf("Test for %d in solution2 failed.\n", n);


 if (Fibonacci_Solution3(n) == expected)

  printf("Test for %d in solution3 passed.\n", n);

 else

  printf("Test for %d in solution3 failed.\n", n);

}


int _tmain(int argc, _TCHAR* argv[])

{

 Test(0, 0);

 Test(1, 1);

 Test(2, 1);

 Test(3, 2);

 Test(4, 3);

 Test(5, 5);

 Test(6, 8);

 Test(7, 13);

 Test(8, 21);

 Test(9, 34);

 Test(10, 55);


 Test(40, 102334155);


 return 0;

}


本文出自 “巖梟” 部落格,請務必保留此出處http://yaoyaolx.blog.51cto.com/10732111/1742164

           

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!https://blog.csdn.net/jiangjunshow