[英]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.