码迷,mamicode.com
首页 > 编程语言 > 详细

c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)

时间:2016-02-15 18:34:07      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:c语言 剑指offer   求斐波拉契数列的第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

c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)

标签:c语言 剑指offer   求斐波拉契数列的第n项 5种方法 算法优化

原文地址:http://yaoyaolx.blog.51cto.com/10732111/1742164

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!