获取第 n 个斐波那契数的简单代码
Simple code to obtain n-th number of Fibonnaci
我只是想生成一段有效的代码来获取斐波那契数列的第n个数字,并使用下面的代码来执行此操作。但是,我Expression: vector subscript out of range
收到错误,不知道为什么会发生。
int Fib(int n)
{
vector<int> output;
output.reserve(n);
output[0] = 1; output[1] = 2;
for(int i = 2; i <=n; ++i)
{
output.push_back(output[i-1]+ output[i-2]);
}
return output[n];
}
原始代码返回 Fib(0( 的无效值(1 而不是 0(https://en.wikipedia.org/wiki/Fibonacci_number。
以下代码修复了此问题和矢量初始化:
int fib(int n)
{
vector<int> output;
output.resize(n+1);
output.clear();
output.push_back(0);
output.push_back(1);
for (int i=2; i <= n; i++)
{
output.push_back(output[i-1] + output[i-2]);
}
return output[n];
}
无论如何,甚至有一个更好的实现,不需要使用向量:
int fib(int n)
{
if ( n == 0 || n == 1 )
return n;
int fib1 = 0;
int fib2 = 1;
int fib = 0;
for ( int i = 2; i < n; i++ )
{
fib = fib1 + fib2;
fib1 = fib2;
fib2 = fib;
}
return fib;
}
std::vector::reserve
只是容器为数据预分配存储的性能提示;它实际上并没有用n
元素填充向量。因此,当您尝试访问元素(如 output[0] = 1
(时,您正在访问不存在的元素。
您可以简单地切换到 std::vector::resize
,它可以执行您想要的操作。请注意,在 thas std::vector::push_back
使算法出错后,您应该这样做
output[n] = output[n-1] + output[n-2];
顺便说一下,这种方法不是很有效,至少由于不必要的内存分配。像这样的东西应该更快:
int Fib(int n)
{
int a = 0, b = 1;
for(int i = 0; i < n; ++i)
{
int t = a + b;
a = b;
b = t;
}
return a;
}
保留 != 调整大小
您不是在插入以后可以使用下标operator[]
访问的默认构造元素,而是暗示分配未初始化的内存,这只会影响容量,而不会影响容器的大小。因此,以这种方式访问元素是无效的。
即使这些预循环线也是无效的
output.reserve(n);
output[0] = 1; output[1] = 2;
您应该宁愿使用 resize()
并注意push_back
随后会增加向量的维度(因此,要么在代码中一直使用 push_back
s,要么执行resize()
并使用下标访问(。
int Fib(int n)
{ // Lacks error checking if n < 2
vector<int> output;
output.resize(n);
output[0] = 1; output[1] = 2;
for (int i = 2; i < n; ++i)
{
output[i] = output[i - 1] + output[i - 2];
}
return output[n-1];
}
额外提示:
如果你只对
n-th
斐波那契数感兴趣,你不需要带有向量的完整历史,你可以缓存序列中的最后两个数字对于大
n
这种方法可能行不通,在对数时间内运行的更聪明的方法(尽管您仍然需要做一些简单的矩阵乘法(可能是以下 [线性递归关系]
此行
output.reserve(n);
不会向量添加元素 - 它只是在内存中为该数量的项目保留空间。它不会用任何东西填充向量 - 您可以通过在返回零的向量上调用 size()
来验证这一点。因此在这里
output[0] = 1; output[1] = 2;
您正在尝试修改特定索引处的值 - 但这些索引上没有任何内容,并且您的索引超出了向量数组边界(如消息所示(。在尝试读取或写入特定索引之前,实际上应该填充向量。
在您的情况下,只需添加
output.push_back(1);
output.push_back(2);
之前您的循环将解决此问题(或者按照其他答案的建议使用 resize
(。
int fib()
{
cout<<"Enter the term";
cin>>n;
int f=0,f1=1,f2=0;
for(i=1;i!=n;i++)
{
f=f1+f2;
f1=f2;
f2=f;
}
if(i==n)
cout<<n<<"'th term is"<<f;
}
是否足够简单,如果我错了,请纠正我
>std::vector::reserve
只增加向量的容量(即分配的空间(,它实际上并没有增加向量的大小(即项目数(。
所以:
output[0] = 1; output[1] = 2;
是不合法的,因为您尝试访问大小为 0 的向量中的前两项。
相反,请执行:
output.push_back(1);
output.push_back(2); // this should probably push back 1 though, if you want the Fibonacci sequence
此外,您尝试向向中添加一个太多的项目,因此将循环更改为:
for(int i = 2; i < n; ++i)
(即使用<
而不是<=
(。
您还必须相应地修改 return 语句:
return output[n - 1];
你应该做这样的事情:
std::vector<int> output;
output.resize(n+1); // resize not reserv & n+1 because the <=n
output[0] = 1; output[1] = 2;
for (int i = 2; i <= n; ++i)
{
output[i]=(output[i - 1] + output[i - 2]); // indexing not push_back
}
顺便说一句,如果你真的想使用似乎不是最佳选择的向量,你最好做一些事情:
std::vector<unsigned long long> output;
output.resize(n+1);
output[0] = 1; output[1] = 2;
const auto end_of_output(std::end(output));
for (auto& it = std::begin(output) + 2; it < end_of_output; ++it){
*it = *(it - 1) + *(it - 2);
}
由于您为n
变量保留了一个空间,因此向量最多可以索引 n-1
,而返回 output[n]
,从而导致错误:vector subscript out of range
。要为最后一个变量留出空间,您应该使用 reserve(n+1)
.但是,请注意,这将是n+1
斐波那契数。
此外,vector.reserve()
将内存分配给向量而不对其进行初始化。因此,您无法访问诸如 output[0]
.相反,您应该push_back
索引 0 和 1 处的值(以及其他值(,或者使用 vector.resize()
然后按索引访问所有元素,而不是使用 push_back
。
有关 resize
和 reserve
之间区别的说明,请参阅此 SO 线程。
- boost::spirit--试图编译大多数简单代码的编译器错误
- 奇怪的 G++ 错误,带有关于左值和赋值的简单代码
- 为什么 for 循环只接受这个简单代码中的最后一个字符串?
- SFML C 为什么在屏幕上没有绘制?(简单代码)
- GoogleMock发出用Eclipse构建C 的简单代码
- 为什么我的简单代码在C++中不起作用?
- PQXX简单代码崩溃了
- 此简单代码的正统代码
- 我在C++文件中的简单代码块上有 2 个错误。错误 C2059:语法错误:"?"。第二智能感知:预期表达式。怎么了?
- 用谷歌基准测试简单代码的问题
- 简单代码给出C 错误C4430和C2143
- 这个带有向量的简单代码有什么问题?
- 优化项目Euler 16的简单代码
- 如何重写此 C++ 简单代码
- 是否有Visual c++编译器在线,以及如何在c++和vs简单代码之间转换
- 简单代码问题-未定义标识符
- OpenCV简单代码编译成功,但在运行时崩溃
- 如何在另一个类中构造一个类?(简单代码)
- 验证给定C++编译器是否将源代码读取为 C++11 的快速简单代码是什么?
- 带有类的 C++ 简单代码