[英]C++ Fibonacci number generator not working. Why?
我只是想知道為什么這種獲取斐波那契數的方法不起作用謝謝。
#include <iostream>
#include <cctype>
#include <cmath>
using namespace std;
int fibonacci()
{
cout << "enter sequence num: " << endl;
int num;
cin >> num;
int list[num] = {0, 1};
int x;
if (num == 1)
{
cout << "the " << num << " fibo num is " << 0 << endl;
}
else if (num == 2)
{
cout << "the " << num << " fibo num is " << 1 << endl;
}
else
{
for (int y = 0; y < num - 2; y++)
{
// get new fibo value
x = list[y] + list[y + 1];
for (int z = 2; z < num; z++)
{
// will append new value to the list
list[z] = x;
}
}
cout << "the " << num << " fibo num is " << list[-1] << endl;
// get the last value which is the fibo value
}
}
int main()
{
fibonacci();
return 0;
}
對於初學者可變長度 arrays 那樣
cin>>num;
int list[num] = {0,1};
不是標准的 C++ 功能。 事實上,計算斐波那契數不需要使用數組。
而且這個聲明
int list[num] = {0, 1};
如果變量num
的輸入值等於1
,則無效。 即使在有條件地支持可變長度 arrays 的 C 中,您也不能在其聲明中初始化可變長度數組。
盡管如此,在這份聲明中
cout<<"the "<<num<<" fibo num is "<<list[-1]<<endl;
表達式list[-1]
訪問數組外部的 memory 調用未定義的行為。
看來你的意思
cout<<"the "<<num<<" fibo num is "<<list[num-1]<<endl;
我將通過以下方式定義 function,如下面的演示程序所示。
#include <iostream>
#include <utility>
unsigned long long Fibonacci( unsigned int n )
{
unsigned long long first = 0, second = 1;
for ( unsigned i = 0; i < n; i++ )
{
first = std::exchange( second, first + second );
}
return first;
}
int main()
{
const unsigned int N = 10;
for ( unsigned int i = 0; i < N; i++ )
{
std::cout << i << ": " << Fibonacci( i ) << '\n';
}
}
程序 output 是
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
來自莫斯科的 Vlad 已經展示了您代碼中的問題。
我想補充一點,根本不需要在運行時計算斐波那契數。 編譯器將成為您的朋友。
超快速和緊湊的解決方案是使用編譯時間計算。 因此,在編譯期間預先計算適合 64 位無符號位的所有可能值。
斐波那契數列的一個重要特性是值呈指數級增長。 因此,integer 數據類型中的所有現有構建將很快溢出。
使用比內特的公式,您可以計算出第 93 個斐波那契數是最后一個適合 64 位無符號值的數。
在編譯期間計算 93 個值是一項非常簡單且快速的任務。
那么,該怎么做呢?
我們首先將計算斐波那契數的默認方法定義為constexpr
function。 迭代和非遞歸。
// 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)... } };
};
這個 function 將被輸入一個 integer 序列 0,1,2,3,4,... 並返回一個std::array<unsigned long long, ...>
與相應的斐波那契數。
我們知道我們最多可以存儲 93 個值。 因此我們制作了下一個 function,它將使用 integer 序列 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
這里有一些不一致的索引。 如果 num = 1,則斐波那契數為 0,如果 num=2,則斐波那契數為 1……但這與聲明 int list[num] = {0,1} 不太匹配,因為索引以 0 開頭.
我重寫了代碼,使第一個數字的索引為 1(list[1]=0 和 list[2]=1)
append 不需要嵌套 for 循環來獲取數組末尾的新總和。 只需一個簡單的 for 循環即可。
I have modified your code below, see below.
#include <iostream>
#include <cctype>
#include <cmath>
using namespace std;
int fibonacci(){
cout<<"enter sequence num: "<<endl;
int num;
cin>>num;
int list[num];
list[1] = 0;
list[2] = 1;
int x;
if(num==1){
cout<<"the "<<num<<" fibo num is "<<0<<endl;
}else if(num==2){
cout<<"the "<<num<<" fibo num is "<<1<<endl;
}else{
for(int y=3;y<=num;y++){
list[y]=list[y-1]+list[y-2];
}
}
cout<<"the "<<num<<" fibo num is "<<list[num]<<endl;
}
int main()
{
fibonacci();
return 0;
}
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.