簡體   English   中英

我的代碼有什么問題? 第 N 個斐波那契數

[英]What is wrong with my code? Nth Fibonacci Number

  public:
  
    long long int lookup[100]={-1};
    long long int nthFibonacci(long long int n){
        // code here
    
        if(lookup[n]==-1){
            if(n<=1) lookup[n]=n;
            else lookup[n]=nthFibonacci(n-1)+nthFibonacci(n-2);
        }
        return lookup[n];
    }
};

這是我的代碼。 它為輸入 2 提供輸出 0,而不是它應該提供 1。

好的,我們正在談論斐波那契數列和記憶。

超快速和緊湊的解決方案是使用編譯時記憶。 因此,在編譯時預先計算所有可能的值,這些值適合 64 位無符號位值。

斐波那契數列的一個重要屬性是值呈指數級增長。 因此,所有現有的內置整數數據類型都會很快溢出。

使用比奈公式,您可以計算出第 93 個斐波那契數是最后一個適合 64 位無符號值的數。

在編譯期間計算 93 個值是一項非常簡單和快速的任務。

那么,怎么辦?

我們首先將計算斐波那契數的默認方法定義為constexpr函數。 迭代和非遞歸。

// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
    // Initialize first two even numbers 
    unsigned long long f1{ 0 }, f2{ 1 };

    // calculating Fibonacci value 
    while (index--) {
        // get next value of Fibonacci sequence 
        unsigned long long f3 = f2 + f1;
        // Move to next number
        f1 = f2;
        f2 = f3;
    }
    return f2;
}

這樣,可以在編譯時輕松計算斐波那契數。 然后,我們用所有斐波那契數字填充std::array 我們還使用constexpr並使其成為帶有可變參數包的模板。

我們使用std::integer_sequence為索引 0,1,2,3,4,5, .... 創建一個斐波那契數。

這很直接,並不復雜:

template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
    return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};

這個函數將輸入一個整數序列 0,1,2,3,4,... 並返回一個std::array<unsigned long long, ...>與相應的斐波那契數列。

我們知道我們最多可以存儲 93 個值。 因此我們創建了一個 next 函數,它將使用整數序列 1,2,3,4,...,92,93 調用上面的函數,如下所示:

constexpr auto generateArray() noexcept {
    return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}

而現在,終於,

constexpr auto FIB = generateArray();

將給我們一個編譯時std::array<unsigned long long, 93>名稱為 FIB 的包含所有斐波那契數。 如果我們需要第 i 個斐波那契數,那么我們可以簡單地寫FIB[i] 運行時不會有計算。

我認為沒有更快或更簡單的方法來計算第 n 個斐波那契數。

請參閱下面的完整程序:

#include <iostream>
#include <array>
#include <utility>
// ----------------------------------------------------------------------
// All the following will be done during compile time

// Constexpr function to calculate the nth Fibonacci number
constexpr unsigned long long getFibonacciNumber(size_t index) {
    // Initialize first two even numbers 
    unsigned long long f1{ 0 }, f2{ 1 };

    // calculating Fibonacci value 
    while (index--) {
        // get next value of Fibonacci sequence 
        unsigned long long f3 = f2 + f1;
        // Move to next number
        f1 = f2;
        f2 = f3;
    }
    return f2;
}
// We will automatically build an array of Fibonacci numberscompile time
// Generate a std::array with n elements 
template <size_t... ManyIndices>
constexpr auto generateArrayHelper(std::integer_sequence<size_t, ManyIndices...>) noexcept {
    return std::array<unsigned long long, sizeof...(ManyIndices)>{ { getFibonacciNumber(ManyIndices)... } };
};

// Max index for Fibonaccis that for in an 64bit unsigned value (Binets formula)
constexpr size_t MaxIndexFor64BitValue = 93;

// Generate the required number of elements
constexpr auto generateArray()noexcept {
    return generateArrayHelper(std::make_integer_sequence<size_t, MaxIndexFor64BitValue>());
}

// This is an constexpr array of all Fibonacci numbers
constexpr auto FIB = generateArray();
// ----------------------------------------------------------------------

// Test
int main() {

    // Print all possible Fibonacci numbers
    for (size_t i{}; i < MaxIndexFor64BitValue; ++i)

        std::cout << i << "\t--> " << FIB[i] << '\n';

    return 0;
}

使用 Microsoft Visual Studio Community 2019 版本 16.8.2 進行開發和測試。

另外使用 clang11.0 和 gcc10.2 編譯和測試

語言:C++17

如果 n <= 1,您不需要執行 lookup[n] = n (這也應該是您比較的情況)。 對於斐波那契,您只需要在第一種情況下返回 n。

我在這里重寫了你的代碼

 long long int nthFibonacci(long long int n)
    {
    if (n <= 1)
       return n;
    return nthFibonacci(n-1) + nthFibonacci(n-2);
    }

暫無
暫無

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

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