奇数Fibonnaci的总和失败了吗?

时间:2017-04-22 02:52:12

标签: javascript

所以我遇到了一个奇怪的错误,即我总结所有的奇数和比数字少的斐波纳西数。

奇怪的是,它适用于低值,但是当我达到10左右的上限值时......它会崩溃codepen.io

这是我到目前为止所做的:

function f(n)
{
    if(n <= 1)
    return n;
  return f(n-1)+f(n-2);
}
function sumFibs(num) {
    var counter = 0;
  var arr = [];
  //Get all Fibbonaci Numbers up to num
    for(let i = 1;i <= num;i++)
  { 
        arr.push(f(i));
  }
  for(let j = 0;j < arr.length;j++)
  {
    if(arr[j] % 2 != 0 && arr[j] <=num)
    {
        counter+= arr[j];
    }
  }
  console.log(counter);
    return counter;
}
sumFibs(10);

基本上我计算的是最高num的纤维,然后我会通过每个小于或等于num的奇数,并将它们加起来。

我得到正确的值(IE为10我得到10,对于4得到5 ....等等......)

但如果我输入类似1000的东西,它似乎只会崩溃?我似乎无法找出任何理由?

1 个答案:

答案 0 :(得分:2)

递归f()函数是表达斐波纳契数计算的逻辑方法,但与迭代方法相比,它并不是非常有效,特别是因为您是在循环内重复调用它。我认为这会让您的浏览器停止运行。每次调用f()时,它都会在循环内通过递归调用自身从头开始计算指定的Fibonacci数 。因此,要获得f(10),它会使用f(9) + f(8)将自己称为两次(然后又会调用f(8)+f(7) { {1}}等等,所以即使这样效率也很低,但实际上您已经知道f(7)+f(6)f(9)是什么,因为您已经在前一个循环中将这些值存储在数组中迭代。

如果你改变你的循环来直接计算每个后续数字而不是调用另一个函数你得到很多更快的代码:

f(8)

有了这样的改变,你的var arr = [1, 1]; // start with the known first two numbers //Get all Fibbonaci Numbers up to num for(let i = 2; i < num; i++) // start the loop at index 2 for the third number { arr[i] = arr[i-2] + arr[i-1]; } 函数甚至可以在几毫秒内为sumFibs()提供结果:

&#13;
&#13;
sumFibs(1000000)
&#13;
&#13;
&#13;

请注意,您的第二个循环中也有一个逻辑错误,即加起来奇数的错误:function sumFibs(num) { var counter = 0; var arr = [1, 1]; //Get all Fibbonaci Numbers up to num for (let i = 2; i < num; i++) { arr[i] = arr[i - 2] + arr[i - 1]; } for (let j = 0; j < arr.length; j++) { if (arr[j] % 2 != 0) { counter += arr[j]; } } return counter; } console.log('10: ' + sumFibs(10)); console.log('100: ' + sumFibs(100)); console.log('1000: ' + sumFibs(1000)); console.log('10000: ' + sumFibs(10000)); console.time('High fib'); console.log('1000000: ' + sumFibs(1000000)); console.timeEnd('High fib');部分需要删除。 && arr[j] <=num中的值是实际的斐波纳契数,但arr是序列号,因此比较它们没有意义。你只需要整个数组中的每个奇数。

但是,如果num太大,您的函数的返回值将不正确。这是因为当你达到80-秒的Fibonacci数时,它比JavaScript可以处理的大而不会失去精度,即大于Number.MAX_SAFE_INTEGER,9,007,199,254,740,991(即2 ^ 53-1)。上面的数字开始变得圆滑,所以你对奇数的测试是不可靠的,因此总和不包括它应该具有的所有数字,或者如果你添加太多JS认为你的结果是{ {1}}。