找到第n个斐波纳契数时出错

时间:2015-06-27 16:42:50

标签: c++

我试图找到第n个斐波那契数字mod 100000,其中n可以达到5000000.

这是我的代码:

#define max_n 5000000

int mod = 100000;
int memo[max_n + 5];

int fib (int n)
{
      if (n == 1) 
           return 0;

      if (n == 2) 
           return 1;

      if (memo[n] > 0) 
           return memo[n];

      memo[n]=(fib(n-1) + fib(n-2))%mod;

      return memo[n];
}

但是当我运行代码时。它给出了运行时错误。请帮忙

主要:

#include <iostream>

using namespace std;

int main()
{

int n, i;

for (i = max_n; i >= 1 ;i--)
{
    fib (i);
}

cin >> n;
cout << memo[n] << endl;

return 0;
}

4 个答案:

答案 0 :(得分:2)

您遇到的错误是堆栈溢出。这是因为为您的线程分配的堆栈是1MB(默认情况下),并且您的程序具有深度为500万的递归函数调用。

为了解决这个问题,您可以反转迭代,如:

int n,i;
for(i=1;i<=max_n;++i)
{
   fib(i);
}

由于fib缓存结果,根本不会有任何递归调用,也不会抛出堆栈溢出异常。

答案 1 :(得分:0)

您编码存储std::vector中获得的Fibonacci列表的所有值,并使fib函数添加std::vector内的最后两个值,然后写入它。这样,您可以避免过多的递归溢出堆栈。唯一的问题是,矢量会变得很大。

答案 2 :(得分:0)

正如Tal Shalti的回答所说,一个简单的解决方案是从前到后填充你的备忘录阵列。

但是,如果将函数设计为迭代函数而不是递归函数,则可以省去专门填充Fibonacci数列表的需要。我就是这样做的:

#include <iostream>
#include <vector>
#include <cassert>

#define CACHE_FIB

using namespace std;

const int MOD = 100000;

vector<int> MEMO{0, 1};

int fib_mod(size_t n) {
    assert(n > 0);
    n -= 1; // zero based

    if(n < MEMO.size())
        return MEMO[n];

    for(size_t i = MEMO.size() - 1; i < n; i++) {
        int next = (MEMO[MEMO.size() - 1] + MEMO[MEMO.size() - 2]) % MOD;
        MEMO.push_back(next);
    }
    return MEMO.back();
}

答案 3 :(得分:0)

可以将诸如斐波那契的LRE(线性递归方程)转换为矩阵乘法。在这种情况下:

F(0) =  |  0  |   (fib( 0))
        |  1  |   (fib(-1))

M =     | 1 1 |   (calculates LRE             to new 1st number)
        | 1 0 |   (copies previous 1st number to new 2nd number)

F(n) = M F(n-1) = matrixpower(M, n) F(0)

您可以使用重复平方(有时称为二进制求幂)将矩阵提升到幂n。整数的示例代码:

    r = 1;             /* result */
    s = m;             /* s = squares of integer m */
    while(n){          /* while exponent != 0 */
        if(n&1)        /*   if bit of exponent set */
            r *= s;    /*     multiply by s */
        s *= s;        /*   s = s squared */
        n >>= 1;       /*   test next exponent bit */
    }

所有这些都将以模数100000完成。对于n <= 5000000,将需要&lt; = 23(log2(5000000))循环以将矩阵提升到幂n。对于fibonacci modulo 100000,模式重复每150000个数字,fib(n + 150000)%100000 == fib(n)%100000 == fib(n%150000)%100000。利用这一点,n%150000的最大值= 149999,最大循环次数为18(log2(149999))。