这个C++代码有什么问题
Anything wrong with this C++ code
如果以下代码有问题,有人可以告诉我吗......在一个问题中,有人问我下面的斐波那契数函数是否有任何问题。
int fib(int n)
{
if (n <= 1) return n;
return fib (n-1) + fib(n-2);
}
其中 n 为 0 ...100
所以我的回答是什么都没有,因为我看不到任何明显的东西。语法似乎很好,从逻辑上讲,这是在计算斐波那契数。我做出这个假设是否正确?
这取决于您询问的问题类型。我在这里看到两个问题:
- 递归。没有理由。只需使用迭代。
- 范围溢出。
int
类型无法容纳范围 [0, 100] 中的所有斐波那契数
这是在 Python 中使用迭代实现 fib 的一个例子(只是因为它可以开箱即用地保存fib(100)
(:
In [16]: def fib(n):
....: curr, next = 0, 1
....: for x in range(n):
....: curr, next = next, curr
....: next += curr
....: return curr
....:
In [17]: fib(100)
Out[17]: 354224848179261915075L
如果答案为时已晚,但您还应该研究此函数的复杂性,以更好地了解为什么它不能正常工作。
因为对于你调用 fib(n-1( 和 fib(n-2( 的函数的每次调用,fib(n( 执行的操作数量约为 2^n。检查以下程序,该程序计算调用 fib(( 的次数:
#include <iostream>
using namespace std;
int cnt = 0;
int fib(int n) {
cnt++;
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int main() {
cout << fib(15) << 'n';
cout << cnt << 'n';
}
所以,如果你想调用fib(100(,它将执行大约10^18个操作,假设你的电脑足够快,可以在1秒内完成10^9个操作,大约需要33年才能完成。
但这会在更早之前导致堆栈溢出错误。
确实,fib(100( 将有超过 19 位数字,这是 long long 可以容纳的最大值,但这并不是您的函数"粘性">的主要原因。
一个好的(也许是最好的(选择是按照上面所说的@soon,使用具有线性复杂性的迭代函数/算法(您的函数是指数级的,在此处阅读更多(。
这是在C++中使用大数字实现的斐波那契函数的代码(实际上还有更多的C,但是,无论如何(:
#include <iostream>
using namespace std;
const int maxsize = 10000; // number of digits
int n;
// note that the digits are keep reversed in the vector
// the bigsum function is as you would use add in math
// a = a + b
void bigsum(int a[], int b[]) { // in a[0] I hold the number of digits of 'a'
int i, t = 0;
for (i = 1; i <= a[0] || i <= b[0] || t; ++i) { // while you still have digits to add
t = t + a[i] + b[i];
a[i] = t % 10;
t /= 10;
}
a[0] = i - 1; // the new a[0]
}
int zero[maxsize];
// a = b
void copy(int a[], int b[]) {
for (int i = 0; i <= b[0]; ++i) {
a[i] = b[i];
}
}
void fib(int n) {
if (n < 0) {
cout << "NA";
} else if (n == 0) {
cout << 0;
} else if (n == 1 || n == 2) {
cout << 1;
} else if (n == 3) {
cout << 2;
} else {
int first[maxsize], second[maxsize], third[maxsize];
copy(first, zero); copy(second, zero); copy(third, zero);
first[0] = first[1] = second[0] = second[1] = 1; // initializing the numbers with 1
third[0] = 1; third[1] = 2; // initializing with 2
for (int i = 4; i <= n; ++i) {
copy(first, second);
copy(second, third); // if you don't understand why these 3, try to do it on a paper
bigsum(third, first);
}
for (int i = third[0]; i >= 1; --i) { // because the digits are reversed
cout << third[i];
}
}
cout << 'n';
}
int main() {
cin >> n;
fib(n);
}
现在 fib 函数适用于更高的数字(10000 位,如果需要更高的数字,只需更改 maxsize 值(,操作总数为 n * NUMBER_OF_DIGITS,约为 n^2(小于 2^n(。
另一个非常好的解决方案是使用 2x2 矩阵,它允许您在 aprox 中计算余数 fib(n( % SOME_NUMBER。log2(n( 运算(您可以使用"平方求幂">,请参阅此处(。在此处阅读有关矩阵解决方案的更多信息。
总之,你的程序不好,因为它以指数级的复杂性运行,而且它使用了太多的堆栈内存(即使它返回正确的值(。
希望您现在了解您的功能问题。再次抱歉,如果这篇文章不应该在这里。
万事如意!
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了