javascript:对斐波那契数列的偶数求和

javascript: summing even members of Fibonacci series

另一个(欧拉计划)斐波那契问题:使用(原版)javascript,我试图对 <= 给定限制的偶数求和:

首先,我的 'if' 陈述有问题,因为某些结果(如下)是错误的:

function fibonacciSum(limit) {
    var limit = limit;
    var series = [1,2];
    var sum = 0;
    var counter = 0;

    for (var i=1; i<=33; i++) { // 33 is arbitrary, because I know this is more than enough
        var prev1 = series[series.length-1];
        var prev2 = series[series.length-2];
        var newVal = prev1+prev2;

        series.push(newVal);
        counter ++;
        console.log("series "+ counter + " is: " + series);

        if (series[i] % 2 === 0 && series[i] <= limit) { // intending to sum only even values less than/equal to arbitrary limit
            // sum = sum + series[i];
            sum += series[i];
        }

        /*
            var sum = series.reduce(function(a,b) {
                /*
                    possible to filter here for even numbers? something like:
                    if (a %2 === 0)
                */
                return a+b;
            });
        */
        console.log("SUM " + counter + ": " + sum);
    } // for loop
} // fibonacci

fibonacciSum(4000000);

结果:

系列 1 是:1,2,3
总和 1: 2
系列 2 是:1,2,3,5
总和 2: 2
系列 3 是:1,2,3,5,8
SUM 3: 2 // 在这里寻找'10'
系列 4 是:1,2,3,5,8,13
总和 4: 10
系列 5 是:1,2,3,5,8,13,21
总和 5: 10
系列 6 是:1,2,3,5,8,13,21,34
SUM 6: 10 // 在这里寻找 '44'

有人可以解释一下为什么这些都没有按预期工作吗?

if (series[i] % 2 === 0) { ...

... 或

if (series[i] % 2 === 0 && series[i] <= limit) { ...

其次,如您所见,我也曾尝试使用 series.reduce(...但我不知道如何仅对偶数求和;是 doable/cleaner 吗?

谢谢,

威士忌 T.

这应该适合你...

var fibonacciSum = function(limit) {
    var nMinus2 = 1, nMinus1 = 2, evensFound = [2], sum = nMinus1;
    while (sum <= limit){
        var n = nMinus1 + nMinus2;
        if (n % 2 == 0){
            sum += n;
            if (sum > limit){
                break;
            }
            evensFound.push(n);
        }
        nMinus2 = nMinus1;
        nMinus1 = n;
    }

    console.log("Evens found - " + evensFound);
  
  return evensFound;
};

var evensFound1 = fibonacciSum(4),
    evensFound2 = fibonacciSum(10),
    evensFound3 = fibonacciSum(60),
    evensFound4 = fibonacciSum(1000);

$(evenResults).append(evensFound1 
                      + "<br/>" + evensFound2
                     + "<br/>" + evensFound3
                     + "<br/>" + evensFound4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="evenResults"></div>

不需要数组。使用三个变量来表示斐波那契数列中的前一个、当前和下一个数字。

我们也可以从 2 和 3 开始序列,因为没有其他偶数会影响结果。

我们用 2 初始化偶数之和,因为它是当前数而且是偶数。在 do...while 中,我们按顺序推进数字,如果新数字是偶数,我们将它们添加到总和中。达到限制时停止。

function fibEvenSum(limit) {
  var prev = 1, 
      current = 2, 
      next;

  var sum = 2;

  do {
     next = prev + current;
     prev = current;
     current = next;

     if (current >= limit)
       break;

     if (current % 2 == 0) 
       sum += current;
  } while (true)

  return sum;
}

可以使用奇数和偶数的属性改进此算法:

odd + odd = even
even + even = even
even + odd = odd

本着您尝试的解决方案的精神 - 使用数组 - 尽管如前所述,它们不是必需的。

var i = 0, sequence = [1, 2], total = 0;

while (sequence.slice(-1)[0] < 4000000) {
    sequence.push(sequence.slice(-1)[0] + sequence.slice(-2)[0]);
}

for ( i; i <= sequence.length; i++ ) {
    if ( sequence[i] % 2 === 0 ) {
        total += sequence[i];
    }
}