zoukankan      html  css  js  c++  java
  • 关于斐波那契数列的3种解法

    1.斐波那契

    关于斐波那契数列的定义和应用网上已经有一大堆介绍了,可以去查一查。我以前只知道用循环和递归这两种方式求,但是最近发现一种矩阵乘方的方式来求解。因此就用C语言实现了这3中方式。

    1. 求斐波那契第n个数,循环
    2. 求斐波那契第n个数,递归(n大了后会有很多重复运算,不推荐)
    3. 矩阵法计算
    #include <stdio.h>
    #include <stdlib.h>
    
    // 求斐波那契第n个数,循环
    long long offer74_fibonacci0(unsigned n)
    {
      if (n <= 1)
        return n;
      long long f0 = 0,f1 = 1, fn;
      while (--n)
      {
        fn = f0 + f1;
        f0 = f1;
        f1 = fn;
      }
      return fn;
    }
    
    // 求斐波那契第n个数,递归(n大了后会有很多重复运算,不推荐)
    long long offer74_fibonacci1(unsigned n)
    {
      return n <= 1 ? n : offer74_fibonacci1(n-1)+offer74_fibonacci1(n-2);
    }
    
    //-----------------------------------------------
    // 矩阵乘方的计算方式
    typedef struct Matrix2By2_t
    {
      long long m00,m01,m10,m11;
    } Matrix2By2;
    
    // 初始化一个矩阵
    Matrix2By2 *InitMatrix(long long m00,long long m01,long long m10,long long m11)
    {
      Matrix2By2 *matrix = (Matrix2By2*)malloc(sizeof(Matrix2By2));
      if (NULL == matrix)
        exit(-1);
    
      matrix->m00 = m00;
      matrix->m01 = m01;
      matrix->m10 = m10;
      matrix->m11 = m11;
      return matrix;
    }
    
    // 2个矩阵相乘,释放内存时注意2个矩阵相同的情况
    Matrix2By2 *MatrixMultiply(Matrix2By2 *matrix1,Matrix2By2 *matrix2)
    {
      Matrix2By2 *tmp = (Matrix2By2*)malloc(sizeof(Matrix2By2));
      if (NULL == tmp)
        exit(-1);
    
      tmp->m00 = matrix1->m00 * matrix2->m00 + matrix1->m01 * matrix2->m10;
      tmp->m01 = matrix1->m00 * matrix2->m01 + matrix1->m01 * matrix2->m11;
      tmp->m10 = matrix1->m10 * matrix2->m00 + matrix1->m11 * matrix2->m10;
      tmp->m11 = matrix1->m10 * matrix2->m01 + matrix1->m11 * matrix2->m11;
    
      if (NULL != matrix1)
        free(matrix1);
      if (matrix1 != matrix2 && NULL != matrix2)
        free(matrix2);
      matrix1 = NULL;
      matrix2 = NULL;
      return tmp;
    }
    
    // 计算斐波那契结果
    Matrix2By2 *MatrixPower(unsigned n)
    {
      if (n <= 0)
        exit(-1);
    
      Matrix2By2 *matrix;
      if (n == 1)
      {
        matrix = InitMatrix(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, InitMatrix(1,1,1,0));
      }
    
      return matrix;
    }
    
    // 矩阵法计算
    long long offer74_fibonacci2(unsigned n)
    {
      if (n <= 1)
        return n;
    
      Matrix2By2 *tmp = MatrixPower(n - 1);
      long long r = tmp->m00;
      if (NULL != tmp)
        free(tmp);
      return r;
    }
    
    // 打印函数
    void offer74_fibonacci_print(const char *topic, unsigned n, long long f(unsigned))
    {
      printf("%s : ", topic);
      for (unsigned i = 0; i < n; ++i)
      {
        printf("%lld,", f(i));
      }
      printf("
    ");
    }
    
    void main(void)
    {
      unsigned n = 20;
    
      offer74_fibonacci_print("fibonacci0", n, offer74_fibonacci0);
      offer74_fibonacci_print("fibonacci1", n, offer74_fibonacci1);
      offer74_fibonacci_print("fibonacci2", n, offer74_fibonacci2);
    }
    
    2.总结

    看了上述代码可以发现,递归最简洁,但是计算过程中会存在大量重复计算,如果求比较大的数时栈内存会消耗比较大。循环的方法是比较容易想到的,但是这种算法的时间复杂度是O(n),矩阵乘方的方式时间复杂度只有O(logN)。以上就是这3中方式的优缺点。

  • 相关阅读:
    java中取两位小数 但不要四舍五入
    从字符串中提取数字 java正则表达式
    SQL实现 列转行(MySQL中)
    sql如何根据时间取出最新的数据记录
    动画 很精辟的
    week 与 strong区别 精辟的解释
    The executable was signed with invalid entitlements新设备run出现这个问题
    在iOS中创建静态库
    网址
    nginx单机1w并发设置
  • 原文地址:https://www.cnblogs.com/janbar/p/13698912.html
Copyright © 2011-2022 走看看