以递归方式获取给定整数中的奇数计数

时间:2018-01-18 18:37:57

标签: javascript recursion

美好的一天,我试图获得给定整数中的奇数的数量,比如15应该返回7,3应该返回1等等...现在我能够在for循环中做到这一点,但是我想现在递归地实现它。这是我的代码:

var count = 0;
function oddCount(n){ 
    if(n !== 0 && !isNaN()) {
        return count;
        if(n%2 === 0) {
            count ++;  
            return oddCount(n-1); 
        } else {
            return oddCount(n-1); 
        }
    }
} // oddCount();

console.log(oddCount(14));

控制台始终返回未定义的值。 感谢您提前支持。 :)

4 个答案:

答案 0 :(得分:3)

正如我在评论中提到的那样,由于您没有将任何内容传递给isNaN,因此存在拼写错误。

但是看一下递归方面:使用递归函数,你几乎从不希望它对它关闭的东西(在你的情况下为count)进行操作。你希望它是纯粹的。

因此,将所有内容保留在函数内(或作为参数传入)。您可以将递归函数视为有点像状态机:每个调用只需要为其单个输入计算出答案,然后将其与递归结果(在这种情况下为aggregate = add)进行聚合。请参阅注释(显然,出于解释的目的,这是冗长的):



function oddCount(n){ 
    // Zero => zero, NaN => NaN
    if (n === 0 || isNaN(n)) {
       return n;
    }
    // n % 2 is 0 for evens, 1 for odds.
    // Count the value for the one *below* the one passed in (since when
    // checking 3 we only want to check 0, 1, and 2, e.g., not the 3 as
    // well).
    // Then simply add in the result of the recursive call:
    --n;
    return n % 2 + oddCount(n);
} // oddCount();

console.log(oddCount(0));  // 0
console.log(oddCount(1));  // 0
console.log(oddCount(2));  // 1 (1)
console.log(oddCount(3));  // 1 (1)
console.log(oddCount(4));  // 2 (1 and 3)
console.log(oddCount(14)); // 7 (1, 3, 5, 7, 9, 11, and 13)




答案 1 :(得分:1)

您不需要在外部跟踪计数,而是尝试增加从函数返回的值。而且,正如其他人所指出的那样,当n%2不为0时,需要增加增量,例如, :

enter code here:

答案 2 :(得分:0)

您的奇怪比较错误,您的isNaN条件也会始终评估true



var count = 0;

function oddCount(n) {
  if (n == 0 || isNaN(n)) {
    return count;
  } else {
    if (n % 2 === 0) { // If n%2 is 0 then n is even.
      return oddCount(n - 1);
    }
    count++;
    return oddCount(n - 1);
  }
}

console.log("Number of ODD numbers: " + oddCount(15));




答案 3 :(得分:0)

  

当我输入大数字时,我的最大调用堆栈大小超出了错误

TJ的回答非常好,平常。我将包括这个答案,因为它解决了堆栈溢出问题。下面,我们来看一下with relevant_ids as ( select distinct(email_campaign_id) from hubspot.email_events a where a.subject in ('subject1', 'subject2', 'subject3') ) select * from hubspot.email_events a where a.email_campaign_id in (SELECT email_campaign_id FROM relevent_ids); 的简化实现。

oddCount

要解决此问题,我们必须将递归调用移至tail position;意味着函数的所有其他评估都是完整的,并且递归调用是函数执行的 last 事物...

我们可以通过多种方式实现这一目标,但是一种多功能技术只需在您的函数中添加一个状态参数(或者更多,如果需要)。在这里,我们添加const oddCount = n => n === 0 ? 0 : (n % 2) + oddCount (n - 1) console.log (oddCount (0)) // 0 console.log (oddCount (1)) // 1 console.log (oddCount (2)) // 1 console.log (oddCount (3)) // 2 console.log (oddCount (4)) // 2 console.log (oddCount (5)) // 3 console.log (oddCount (15)) // 8 // i can't do it, captain! console.log (oddCount (100000)) // RangeError: Maximum call stack size exceeded表示奇数的累积总和,并将默认值设置为acc

0

最重要的是,现在注意const oddCount = (n, acc = 0) => n === 0 ? acc : oddCount (n - 1, acc + (n % 2)) console.log (oddCount (0)) // 0 console.log (oddCount (1)) // 1 console.log (oddCount (2)) // 1 console.log (oddCount (3)) // 2 console.log (oddCount (4)) // 2 console.log (oddCount (5)) // 3 console.log (oddCount (15)) // 8 // but still broken??? console.log (oddCount (100000)) // RangeError: Maximum call stack size exceeded的位置 - oddCount的所有参数都可以完全评估,只剩下要做的事情是重复oddCount - 我们已经实现了尾巴 - 递归形式!

oddCount

在支持尾部调用消除的语言中,只要您需要避免堆栈错误。但是截至今天,JavaScript还没有这样的优化。 ES6标准包括对尾部呼叫消除的支持,但是在it became politics行的某处,优化似乎暂时停留在特征边缘。

虽然没问题。 JavaScript已经支持// ... : oddCount (n - 1, acc + (n % 2)) 的无限循环,所以我们可以invent our own mechanism编写堆栈安全的递归函数,即使在没有尾调用消除的语言中也是如此。酷!

while