var x = 0;
var y = 1;
var z;
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
alert(x + y);
fib[i] = x + y;
x = y;
z = y;
}
我尝试生成一个简单的斐波那契数列,但没有输出。
请问有人能告诉我出了什么问题吗?
var x = 0;
var y = 1;
var z;
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
alert(x + y);
fib[i] = x + y;
x = y;
z = y;
}
我尝试生成一个简单的斐波那契数列,但没有输出。
请问有人能告诉我出了什么问题吗?
最近我被问到了这个问题,这是我的解决方案:
function fib(n) {
const arr = [0,1]; // the inital array, we need something to sum at the very beginning
for (let i = 2; i <= n; i++) { // we want the last number, so don't forget the '=' sign
let a = arr[i-1]; // previous Number
let b = arr[i-2]; // the one before that
arr.push(a+b); // push the result
}
return arr; // if you want the n-th number, just return arr[n] or arr.length - 1
}
console.log(fib(4));
递归解决方案如下:
// NOTE: This has extremly bad performance => Exponential time complexity 2^n
function fib(n) {
if (n < 2) {
return n;
}
return fib(n-1) + fib(n-2);
}
console.log('The n-th fibonacci number: ', fib(6));
console.log('The entire fibonacci sequence: ');
// Let's see the entire fibonacci sequence
for (let i = 0; i <= 6; i++) {
console.log(fib(i));
}
// LET'S CREATE A MEMO FUNCTION
// (and use it on the recursive **fib** function from above):
// We want to pass in a function which is going to, eventually,
// use this utility function
function memo(fn) {
const cache = {};
// let's make it reusable, and by that I mean, let's assume that
// we don't know the number of arguments that will be eventually passed in
return function(...args) {
// if we already call this function with the same args?
// YES => return them
if(cache[args]) {
console.log('cached', args[0]);
return cache[args];
}
// otherwise, we want to call our function
// (the one using this 'memo' function) and pass in the arguments
// w/ the help of 'apply'
const res = fn.apply(this, args);
cache[args] = res;
// we want to store the result, so later if we'll be able to
// return that if the args don't change
console.log('not cached', args[0]);
return res; // don't forget to return the result of it :)
}
}
// Now, let's use the memoized function:
// NOTE: Remember the above function has to change in a way
// that it calls the memoized function instead of itself
function fastFib(n) {
// SAME LOGIC AS BEFORE
if (n<2) {
return n;
}
// But, here is where the 'magic' happens
// Very important: We want to call the instantiated 'fibMemo' function
// and NOT 'fastFib', cause then it wouldn't be so fast, right :)
return fibMemo(n-1) + fibMemo(n-2);
}
// DO NOT CALL IT, JUST PASS IT IN
const fibMemo = memo(fastFib);
// HERE WE WANT TO PASS IN THE ARGUMENT
console.log(fibMemo(6));
function fib(n){
if (n <= 2) return 1;
return fib(n-1) + fib(n-2);
}
console.log(fib(10)) //55 // Pass on any value to get fibonacci of.
我之前遇到的一个解决方案
function fib(n) {
if(n<0) throw new Error('Incorrect number in a Fibonacci sequence');
const phi = (1 + Math.sqrt(5)) / 2;
return Math.round(Math.pow(phi, n) / Math.sqrt(5));
}
时间复杂度 O(1)
空间复杂度 O(1)
参考资料: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html
const fibBigInt = (n) => {
if (n <= BigInt(1)) {
return n
}
return fibonacciBigInt(n - BigInt(1)) + fibonacciBigInt(n - BigInt(2))
}
const fibonacciBigInt = _.memoize(fibBigInt)
console.log(fibonacciBigInt(125n))
输出:59425114757512643212875125n
来源:https://github.com/bertolo1988/my-util-js-functions/blob/main/src/fibonacci/fibonacci.js
var a = -1;
var b=0;
var temp =0;
var arry = [];
for(var i=1;i<100;i++){
temp = a+b;
a=b;
b=temp;
arry.push(b*-1);
}
console.log(arry);
function getFibonacciNumbers(n) {
var sequence = [0, 1];
if (n === 0 || n === 1) {
return sequence[n];
}
else {
for (var i = 2; i < n; i++ ) {
var sum = sequence[i - 1] + sequence[i - 2];
sequence.push(sum);
}
return sequence;
}
}
console.log(getFibonacciNumbers(0));
console.log(getFibonacciNumbers(1));
console.log(getFibonacciNumbers(9));
另一个解决方案可能是:
const fib = (num) => {
if(num === 0) return 0;
const arr=[0,1];
let counter=2;
while(counter <=num){
arr[counter]=arr[counter -1] + arr[counter -2]
counter ++
}
return arr
}
该函数根据给定的限制返回斐波那契数列的数组。
fib(5) // returns [0, 1, 1, 2, 3, 5]
你可以以函数式的方式使用递归并缓存结果。
const fibonacci = (n, cache = {1: 1, 2: 1}) =>
cache[n] || (cache[n] = fibonacci(--n, cache) + fibonacci(--n, cache));
console.log(fibonacci(1000));
console.log(fibonacci(100));
console.log(fibonacci(10));
这里有另一个使用 proper tail call 的例子。
递归内部的 fib
函数可以重复使用堆栈,因为生成下一个数字所需的所有内容(数字数组)都作为参数传入,无需评估其他表达式。
然而,ES2015 引入了尾调用优化。
另外一个缺点是它在每次迭代中获取数组长度(但仅一次),以生成下一个数字并按其索引获取数组元素(虽然比 pop 或 splice 或其他数组方法更快),但我没有对整个解决方案进行性能测试。
var fibonacci = function(len) {
var fib = function(seq) {
var seqLen = seq.length;
if (seqLen === len) {
return seq;
} else {
var curr = seq[seqLen - 1];
var prev = seq[seqLen - 2];
seq[seqLen] = curr + prev;
return fib(seq);
}
}
return len < 2 ? [0] : fib([0, 1]);
}
console.log(fibonacci(100));
var sequence = [0,1];
var range = 10;
for(var i = 0; i < range-2; i++){
sequence.push(sequence[i]+sequence[i+1]);
}
console.log(sequence);
fib(0)
或fib(1)
也是错误的。 - vsync