简体   繁体   English

相互递归的功能-锻炼对我没有意义

[英]Mutually recursive functions - exercise not making sense to me

I know this is a silly way to determine even-odd numbers. 我知道这是确定奇数的愚蠢方法。 It is just a lesson in recursion, and probably some other concepts as well. 这只是递归的一课,可能还有其他一些概念。

The problem. 问题。

When I follow the logic, it looks like it doesn't matter what value you give "n", it will always eventually equal "0" and always end up "false". 当我遵循逻辑时,您给“ n”赋值似乎无关紧要,它最终总是等于“ 0”,总是以“ false”结尾。

What is going on? 到底是怎么回事?

function isOdd(x) {
    return !isEven(x);    
}

function isEven(x) {
    if(x===0) {
        return true;
    } else {
        return isOdd(x-1);
    }
}

This is how isOdd returns true on an even number: 这是isOdd对偶数返回true的方式:

When you pass 2 to isOdd, it will forward this to isEven. 当您将2传递给isOdd时,它将把它转发给isEven。 Your call stack now looks like this (newest function is up): 现在,您的调用堆栈如下所示(最新功能已启用):

isEven(2)
isOdd(2)
main

isEven will now call isOdd with 1: isEven现在将以1调用isOdd:

isOdd(1)
isEven(2)
isOdd(2)
main

isOdd will again forward this to isEven: isOdd将再次将此转发给isEven:

isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

the whole happens again with 0 整个事件再次以0发生

isEven(0)
isOdd(0)
isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

isEven now terminates with true, and the whole call-stack is rewinded. isEven现在以true终止,并且倒退了整个调用堆栈。 True is returned to isOdd: True返回给isOdd:

isOdd(0)   <-true
isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

isOdd will negate the return value, and thus return false to isEven: isOdd将使返回值取反,从而向isEven返回false:

isEven(1) <- false
isOdd(1)
isEven(2)
isOdd(2)
main

isEven again returns the result as-is to isOdd isEven再次将结果原样返回给isOdd

isOdd(1) <- false
isEven(2)
isOdd(2)
main

isOdd negates and returns: isOdd取反并返回:

isEven(2) <- true
isOdd(2)
main

isEven returns as-is: isEven照原样返回:

isOdd(2) <- true
main

isOdd negates and returns to main: isOdd取反并返回main:

main <- false

this is how isOdd returns false on an uneven number: 这是isOdd在不均匀数上返回false的方式:

When isEven terminates, the call-stack looks like that. 当isEven终止时,调用堆栈看起来像那样。

isEven(0)
isOdd(0)
isEven(1)
isOdd(1)
main

isOdd receives true: isOdd收到true:

isOdd(0) <-true
isEven(1)
isOdd(1)
main

isOdd negates: isOdd取反:

isEven(1) <- false
isOdd(1)
main

isEven returns the unchanged value: isEven返回不变的值:

isOdd(1) <- false
main

isOdd negates and returns to main: isOdd取反并返回main:

main <- true

So whats the explanation? 那是什么解释呢?

The whole trick is that when you have an odd number, there is an even number of negations in the call-stack. 整个技巧是,当您有奇数时,调用堆栈中的否定数将为偶数。 When you negate a boolean value an even number of times, it comes out as it was before. 当您对布尔值取反数次时,它就会像以前一样出现。 When you have an even number, you have an odd number of negations, and the result is changed. 当您有偶数时,您有奇数个负数,结果将更改。

When I follow the logic, it looks like it doesn't matter what value you give "n", it will always eventually equal "0" and always end up "false". 当我遵循逻辑时,您给“ n”赋值似乎无关紧要,它最终总是等于“ 0”,总是以“ false”结尾。

you want to keep in mind how many isOdd are there in the stack trace. 您要记住堆栈跟踪中有多少isOdd。 for instance: given x = 2 例如:给定x = 2

isOdd(2) => !isEven(2) => !(isOdd(1)) => !(!isEven(1)) => !(!(isOdd(0))) => !(!(!isEven(0))) => !(!(!(true)))

The code works for me. 该代码对我有用。 I tried it in Firefox and IE. 我在Firefox和IE中尝试过。

<html>
<head>
<script language="javascript">
function isOdd(x) {
    return !isEven(x);    
}

function isEven(x) {
    if(x===0) {
        return true;
    } else {
        return isOdd(x-1);
    }
}

alert(isOdd(6));

</script>

</head>
<body>

</body>
</html>

Recursive solutions have two requirements: a base case and an inductive step. 递归解决方案有两个要求:基本案例和归纳步骤。 In this example, the base case is that 0 is even. 在此示例中,基本情况是0为偶数。 As it's the base case, it's expected and normal that all invocations eventually "chip down" to it. 由于这是基本情况,因此所有调用最终都将“归根到底”是正常且正常的。 The inductive step is that a number is even if it's one larger than an odd number. 归纳步骤是一个数字即使比奇数大一个偶数。 But that's not a true induction step, because it defines evenness in terms of oddness. 但这不是真正的归纳步骤,因为它根据奇数来定义均匀性。 So there's another rule required, that a number is odd if it's not even. 因此,还需要另一个规则,即如果数字不是偶数,则该数字为奇数。 Showing rigorously that this terminates is a little tricky, but Phillipp's stack diagram is a decent demonstration of the fact. 严格显示该终止有点棘手,但是Phillipp的堆栈图很好地证明了这一事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM