zoukankan      html  css  js  c++  java
  • bug调试---1、斐波那契数列的矩阵快速幂解法bug

    bug调试---1、斐波那契数列的矩阵快速幂解法bug

    一、总结

    一句话总结:

    发现问题出在矩阵的快速幂里面,因为函数传n过去的时候指定的是int,而本题的n<2^63,所以n本来应该是long long类型的
    错误原因:这里的n传参写成了int
    
    //矩阵的快速幂
    //这里的n写成int类型有问题,这里要是long long
    Matrix pow(Matrix a, long long n)
    {
        Matrix ans, base = a;
        ans.row = 2; ans.column = 2;
        ans.v[1][1] = ans.v[2][2] = 1;
        while (n)
        {
            if (n % 2 == 1)
                ans = multiply(ans, base);
            base = multiply(base, base);
            n = n / 2;
        }
        return ans;
    }

    1、解决斐波那契数列矩阵快速幂代码的bug的启示?

    a、出现问题,要分析问题出现的原因,这样问题就比较好比较快的解决
    b、或者可以参照别人的解决方式(代码),这样站在别人的肩膀上,也很快

    2、解决bug如果没法看日志,其它一个比较快的方法是什么,比如(斐波那契数列矩阵快速幂代码的bug)?

    二分法测bug,我们拿有问题的程序和标准程序的答案来做对比,逐步大批量的增大n,看看问题出现在哪个节点

    二、斐波那契数列的矩阵快速幂解法bug

    博客对应课程的视频位置:

    1、问题

    求斐波那契数列第n项 mod 10^9+7的值
    【数据范围】
    对于100%的数据,1<=n<2^63。

    题目位置:P1962 斐波那契数列 - 洛谷 | 计算机科学教育新生态
    https://www.luogu.com.cn/problem/P1962

    这个数据量O(n)的算法肯定过不了,要O(logn)

    所以可以用矩阵快速幂解法

    结果代码写出来,

    百分之80的数据是对的,只有20%不对,这不对的百分之20,全部是数据量比较大的情况

     

    2、解决过程

    出现问题,要分析问题出现的原因,这样问题就比较好比较快的解决
    或者可以参照别人的解决方式,这样站在别人的肩膀上,也很快

    这个问题后面的项和前面的项是相关的,所以如果前面的项出错了,那么后面的一般会出错



    我们拿有问题的程序和标准程序的答案来做对比
    逐步大批量的增大n,看看问题出现在哪个节点
    可以二分法测bug
    我们有可以来打印前1-200的结果,比较是否有问题
    测试发现
    n为int最大值之前都是没有问题的
    10 0000 0000:10亿,21亿都是没有问题
    当n超过int之后,两个程序的结果就不一样了,
    证明肯定是因为n(1<=n<2^63)太大了,
    导致超过int出现问题,
     
    确定问题出现的原因,那么可以逐步排查代码
    发现问题出在矩阵的快速幂里面
    因为函数传n过去的时候指定的是int
    而n本来应该是long long类型的

    错误原因:这里的n传参写成了int

    //矩阵的快速幂
    //这里的n写成int类型有问题,这里要是long long
    Matrix pow(Matrix a, long long n)
    {
        Matrix ans, base = a;
        ans.row = 2; ans.column = 2;
        ans.v[1][1] = ans.v[2][2] = 1;
        while (n)
        {
            if (n % 2 == 1)
                ans = multiply(ans, base);
            base = multiply(base, base);
            n = n / 2;
        }
        return ans;
    }

    3、完整斐波那契数列的矩阵快速幂解法

     1 #include <iostream>
     2 #include <cstring>
     3 using namespace std;
     4 const int mod = 1000000007;
     5 
     6 struct Matrix
     7 {
     8     //这里要用long long
     9     long long v[3][3];
    10     int row, column;
    11     Matrix()
    12     {
    13         memset(v, 0, sizeof(v));
    14     }
    15 };
    16 
    17 //矩阵乘法
    18 Matrix multiply(Matrix a, Matrix b)
    19 {
    20     Matrix ans;
    21     ans.row = a.row;
    22     ans.column = b.column;
    23     for (int i = 1; i <= a.row; ++i)
    24     {
    25         for (int j = 1; j <= b.column; ++j)
    26         {
    27             for (int k = 1; k <= a.column; ++k)
    28             {
    29                 ans.v[i][j] += (a.v[i][k] * b.v[k][j]) % mod;
    30                 ans.v[i][j] %= mod;
    31             }
    32         }
    33     }
    34     return ans;
    35 }
    36 
    37 //矩阵的快速幂
    38 //这里的n有问题,这里要是long long
    39 Matrix pow(Matrix a, long long n)
    40 {
    41     Matrix ans, base = a;
    42     ans.row = 2; ans.column = 2;
    43     ans.v[1][1] = ans.v[2][2] = 1;
    44     while (n)
    45     {
    46         if (n % 2 == 1)
    47             ans = multiply(ans, base);
    48         base = multiply(base, base);
    49         n = n / 2;
    50     }
    51     return ans;
    52 }
    53 
    54 int main()
    55 {
    56     long long n;
    57     cin >> n;
    58     Matrix a, last, ans;
    59     a.row = 2;
    60     a.column = 2;
    61     a.v[1][1] = a.v[1][2] = a.v[2][1] = 1;
    62 
    63     last.row = 2;
    64     last.column = 1;
    65     last.v[1][1] = last.v[2][1] = 1;
    66     if (n == 1 || n == 2)
    67         cout << 1 << endl;
    68     else
    69     {
    70         ans = pow(a, n - 2);
    71         ans = multiply(ans, last);
    72         cout <<ans.v[1][1] << endl;
    73     }
    74     return 0;
    75 }

     
  • 相关阅读:
    抽象类和接口【转】
    JQuery中的事件总结
    ExecuteNonQuery()返回受影响行数不适用select语句
    用js获取对象之前首先检测元素是否存在
    页面如何自动出现滚动条(overflow属性用法)
    今天调试程序遇到了一个致命问题语法错误操作符丢失
    JQuery选择器学习总结JQuery选择器
    css !important用法CSS样式使用优先级判断
    JQuery操作DOM总结
    JQuery特效与动画总结
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13085628.html
Copyright © 2011-2022 走看看