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

在每一种编程语言里,斐波那契数列的计算方式都是一个经典的话题。它可能有很多种计算方式,例如:递归、迭代、数学公式。哪种算法最容易理解,哪种算法是性能最好的呢?

这里给大家分享一下我对它的研究和总结:下面是几种常见的代码实现方式,以及各自的优缺点、性能对比。

Iteration

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var watch = new Stopwatch();
        watch.Start();
        var r = Fibonacci().Take(40).Last();
        watch.Stop();
        Console.WriteLine($"计算结果:{r},耗时:{watch.Elapsed}");
        Console.ReadLine();
    }

    private static IEnumerable<int> Fibonacci()
    {
        int current = 1, next = 1;
        while (true)
        {
            yield return current;
            next = current + (current = next);
        }
    }
}

计算结果:102334155,耗时:00:00:00.0029930

Recursion

using System;
using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        var watch = new Stopwatch();
        watch.Start();
        Func<int, int> fib = null;
        fib = x => x < 2 ? x : fib(x - 1) + fib(x - 2);
        var r = fib(40);
        watch.Stop();
        Console.WriteLine($"计算结果:{r},耗时:{watch.Elapsed}");
        Console.ReadLine();
    }
}

计算结果:102334155,耗时:00:00:00.7022325

Tail Recursion

using System;
using System.Diagnostics;
using System.Threading;

public class Program
{
    public static void Main()
    {
        var watch = new Stopwatch();
        watch.Start();
        Func<int, int, int, int> fib = null;
        fib = (n, a, b) => n == 0 ? a : fib(n - 1, b, a + b);
        var r = fib(40, 0, 1);
        watch.Stop();
        Console.WriteLine($"计算结果:{r},耗时:{watch.Elapsed}");
        Console.ReadLine();
    }
}

计算结果:102334155,耗时:00:00:00.0001280



这几种实现方式总结:

  • 迭代

代码逻辑清晰,容易理解,性能中等。

  • 递归

代码最为简洁,逻辑最清晰,最容易理解,性能最差。

  • 尾递归

性能最好,代码逻辑稍微复杂。

由此可见,不同的算法对程序的性能影响是十分巨大的,甚至是上千倍以上的差距。

原文地址:https://www.cnblogs.com/haue/p/Fibonacci.html

时间: 2024-10-06 12:16:39

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

NYOJ 461-Fibonacci数列(四)(求斐波那契数列前4位)

题目地址:NYOJ 461 思路:斐波那契数列的通项公式为 然后下一步考虑如何产生前4位: 先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);假设给出一个数10234432, 那么log10(10234432)=log10(1.0234432*10^7)[用科学记数法表示这个数]=log10(1.0234432)+7; log10(1.0234432)就是log10(10234432)的小数部分. log10(1.0234432)=0.0

随机求斐波拉契数列第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:f(n)=f(n-1)+f(n-2) 请求出 f(f(n)),由于结果很大请 对答案 mod 10^9+7; 1<=n<=10^100; 用矩阵乘法+快速幂求斐波那契数列是经典应用: 矩阵公式 C i j=C i k *C k j; 根据递推式 构造2*2矩阵: 原始矩阵 1 0 0 1 矩阵 2 1 1 1 0 原始矩阵与矩阵 2相乘达到转化状态效果: 对矩阵二进行快速幂 乘法:达到快速转化矩阵的效果: 即使达到快速转化状态:那么大的数据范围也很难求解: 高精?这有

求斐波那契数列的第n个数(递归、非递归)

用递归的方式求斐波那契数列的第n个数. 用非递归的方式求斐波那契数列的第n个数. 定义: 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368 特别指出:第0项是0,第1项是第一个1. 这个数列从第2项开始,每一项都等于前两项之和. #include<stdio.h> #include<stdlib.

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

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

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 <

利用矩阵求斐波那契数列

利用矩阵求斐波那契数列 flyfish 2015-8-27 矩阵(matrix)定义 一个m*n的矩阵是一个由m行n列元素排成的矩形阵列.矩阵里的元素可以是数字符号或者数学式. 形如 {acbd} 的数表称为二阶矩阵,它由二行二列组成,其中a,b,c,d称为这个矩阵的元素. 形如 {x1x2} 的有序对称为列向量Column vector 设 A={acbd} X={x1x2} 则 Y={ax1+bx2cx1+dx2} 称为二阶矩阵A与平面向量X的乘积,记为AX=Y 斐波那契(Fibonacci

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

未完成,只能假设知道是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

javascript求斐波那契数列

斐波那契数列:1,1,2,3,5,8,.... <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>斐波那契数列</title> <style type="text/css"> html,body{ padding: 0;margin: 0; width: 100%; heig