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;

}

时间: 2024-08-02 02:43:35

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

poj 3070 Fibonacci (矩阵快速幂求斐波那契数列的第n项)

题意就是用矩阵乘法来求斐波那契数列的第n项的后四位数.如果后四位全为0,则输出0,否则 输出后四位去掉前导0,也...就...是...说...输出Fn%10000. 题目说的如此清楚..我居然还在%和/来找后四位还判断是不是全为0还输出时判断是否为0然后 去掉前导0.o(╯□╰)o 还有矩阵快速幂的幂是0时要特判. P.S:今天下午就想好今天学一下矩阵乘法方面的知识,这题是我的第一道正式接触矩阵乘法的题,欧耶! #include<cstdio> #include<iostream>

求斐波那契数列的相邻两项的比值,精确到小数后三位。

未完成,只能假设知道是9和10代入. 代码如下: package zuoye; import java.math.BigDecimal; /* * 求斐波那契数列的相邻两项的比值,精确到小数后三位. * p1,p2,p3......pi,pj,...求pi/pj * 1 1 2 3 5 8 13 * 5/8,8/13,...收敛 */ public class Test { static double feibo(int x){ if(x==1||x==2) return 1; return f

随机求斐波拉契数列第n位的代码

1------------------------------------------------------------ package oo.day02;import java.util.Scanner;public class FibonacciSequence { public static void main(String[] args) { System.out.println("请输入斐波拉契数列第n项,n>0"); Scanner scan=new Scanner

求斐波那契数列第n位的几种实现方式及性能对比(c#语言)

在每一种编程语言里,斐波那契数列的计算方式都是一个经典的话题.它可能有很多种计算方式,例如:递归.迭代.数学公式.哪种算法最容易理解,哪种算法是性能最好的呢? 这里给大家分享一下我对它的研究和总结:下面是几种常见的代码实现方式,以及各自的优缺点.性能对比. Iteration using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; public class Progr

求斐波那契数列的第n项值——9

写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 0            n = 0 F(n) =  1            n = 1 F(n-1)+F(n-2)    n > 1 也就是斐波那契数列为{0,1,1,2,3,5,8,13,21,......F(n-1)+F(n-2)}: 首先可以想到,因为要求第n个斐波那契数,就需要知道第n-1和第n-2个斐波那契数,而求第n-1个斐波那契数就需要知道第n-2个和第n-3个斐波那契数,第n-2个斐波

[发布] 矩阵乘法及其对于编程求斐波那契数列的某一项的应用

需要PDF的读者可以向我索要. 如果发现有翻印与用于商业用途,将予追究. ======================================= 编者注:本文中如果没有特殊说明,除法均只取整数部分,忽略小数部分. 感谢大家对我的支持!同时感谢ysy大聚聚.

01-封装函数求斐波那契数列第n项

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> //需求:封装一个函数,求斐波那契数列的第n项 alert(getValue()); //定义一个函数 function getValue(n){ //回顾

黑马入学基础测试(三)求斐波那契数列第n项,n&lt;30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

.获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复读取 自己写的代码: package com.itheima; import java.util.Scanner; public class Test3 { /** * 3.求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55 * * @author

【c语言】求斐波那契数列的前40个数。特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和

// 求斐波那契数列的前40个数.特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和 #include <stdio.h> int main() { int a = 1; int b = 1; int c,i; printf("%d\t%d\t",a,b); for(i = 3; i <= 40; i++) { c = a + b; printf("%d\t",c); a = b; b = c; } printf("\n&quo