美好的一天,我试图获得给定整数中的奇数的数量,比如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));
控制台始终返回未定义的值。 感谢您提前支持。 :)
答案 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