我正在尝试将前100个斐波那契数字输出到.txt文件。我让它运行,但它需要一段时间。斐波那契或斐波纳契2会更快吗?下面的代码使用第一个。
#!/usr/bin/env node
var fs = require('fs');
// Fibonacci
// http://en.wikipedia.org/wiki/Fibonacci_number
var fibonacci = function(n) {
if(n < 1) { return 0;}
else if(n == 1 || n == 2) { return 1;}
else if(n > 2) { return fibonacci(n - 1) + fibonacci(n - 2);}
};
// Fibonacci: closed form expression
// http://en.wikipedia.org/wiki/Golden_ratio#Relationship_to_Fibonacci_sequence
var fibonacci2 = function(n) {
var phi = (1 + Math.sqrt(5))/2;
return Math.round((Math.pow(phi, n) - Math.pow(1-phi, n))/Math.sqrt(5));
};
// Find first K Fibonacci numbers via basic for loop
var firstkfib = function(k) {
var i = 1;
var arr = [];
for(i = 1; i < k+1; i++) {
var fibi = fibonacci(i);
arr.push(fibi);
// Print to console so I can monitor progress
console.log(i + " : " + fibi);
}
return arr;
};
var fmt = function(arr) {
return arr.join(",");
};
var k = 100;
// write to file
var outfile = "fibonacci.txt";
var out = fmt(firstkfib(k));
fs.writeFileSync(outfile, out);
console.log("\nScript: " + __filename + "\nWrote: " + out + "\nTo: " + outfile);
答案 0 :(得分:1)
通常,递归函数“更清晰”,“更容易”编写,但通常需要更多的资源(主要是由于堆栈的累积而导致的内存)。在你的情况下,首先获得100的最佳方法是使用一个简单的循环来编程,该循环将计算下一个斐波那契数列并将其添加到列表中。
double a[100];
a[0] = 1;
a[1] = 1;
K=2;
Do{
{
a[k] = a[k - 2] + a[k- 1];
k++;
}While (k!=100)
答案 1 :(得分:1)
递归的斐波纳契函数以错误的方式实现。本文Recursion and Fibonacci Numbers讨论了递归实现它的正确方法。对于那些懒得阅读的人来说,这是他们的代码(它在C中,但翻译起来不应该太难):
unsigned long fib(unsigned int n)
{
return n == 0 ? 0 : fib2(n, 0, 1);
}
unsigned long fib2(unsigned int n, unsigned long p0, unsigned long p1)
{
return n == 1 ? p1 : fib2(n - 1, p1, p0 + p1);
}
更高效的实现会在计算斐波纳契序列时缓存它们的值:
var cache = [];
var fibonacci = function(n) {
if(cache.length > n) return cache[n];
return (cache[n] = fib2(n, 0, 1));
};
var fib2 = function(n, p0, p1) {
if(cache.length > n) return cache[n];
return n == 1 ? p1 : (cache[n] = fib2(n - 1, p1, p0 + p1));
};
我真的不懂语言,因此代码可能存在一些问题,但这至少是它的要点。
答案 2 :(得分:1)
对于你的问题,我们不能比O(n)做得更好,因为你需要产生所有前n个(n = 100)数。
有趣的是,如果你只需要第n个fib数,那么也存在一个O(log n)解决方案。
算法很简单:使用Divide and Conquer方法找出矩阵A的n次方并报告第(0,0)个元素,其中
A = |1 1 |
|1 0 |
递归
A^n = A^(n/2) * A^(n/2)
时间复杂度:
T(n) = T(n/2) + O(1) = O(logn)
如果你用一张纸来考虑它,你会发现证据很简单并且基于归纳原理。 如果您仍需要帮助,请参阅this link
注意:当然你可以迭代计算A,A ^ 2,A ^ 3等等。但是,与其他答案中描述的其他更简单的解决方案相比,使用它是没有意义的。 (由于纯粹的代码复杂性)
答案 3 :(得分:0)
这是一种非常天真的计算方法。尝试做类似的事情:
long[] a = new long[100];
a[0] = 1;
a[1] = 1;
for (int i = 2; i < 100; ++i)
{
a[i] = a[i - 2] + a[i - 1];
}
for (int i = 0; i < 100; ++i)
Console.WriteLine(a[i]);
这样你就得到一个线性时间O(n)