簡體   English   中英

查找第n個斐波那契數時出錯

[英]Error in finding nth fibonacci number

我試圖找到第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;
}

您得到的錯誤是堆棧溢出。 這是由於為您的線程分配的堆棧為1MB(默認情況下),並且您的程序具有深度為500萬的遞歸函數調用。

為了解決此問題,您可以像這樣反轉迭代:

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

由於fib緩存了結果,因此根本不會進行任何遞歸調用,也不會引發堆棧溢出異常。

你代碼存儲你在得到斐波那契列表中的所有值std::vector ,使FIB函數添加最后兩個值內std::vector ,然后寫它。 這樣,您可以避免過多的遞歸導致堆棧溢出。 唯一的問題是,向量將變得巨大。

正如Tal Shalti的回答所說,一個簡單的解決方案是從前到后填充您的備忘錄數組。

但是,如果將函數設計為迭代的而不是遞歸的,則可以省去專門填充斐波那契數字列表的需要。 這是我的處理方式:

#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();
}

諸如斐波納契的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,將需要<= 23(log2(5000000))個循環才能將矩陣求冪n。 對於以100000為模的斐波那契模,該模式每150000個數字重復一次,即fib(n + 150000)%100000 == fib(n)%100000 == fib(n%150000)%100000。 利用此優勢,n%150000 = 149999的最大值,最大循環數為18(log2(149999))。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM