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

猜你喜欢

转载自blog.csdn.net/qq_43667626/article/details/86159169
今日推荐