递归检查奇数或偶数

时间:2017-06-07 21:59:30

标签: python recursion

在此代码中:

def is_even(x):
  if x == 0:
    return True
  else:
    return is_odd(x-1)

def is_odd(x):
  return not is_even(x)

print(is_even(2))
print(is_odd(2))

我一直在脑子里想着这个,并想知道它是如何运作的。在我看来,x中的is_even(x)最终每次都会返回True。但是,当我运行代码时,它完全正常并且适当地返回TrueFalse。有人能解释一下这是怎么回事吗?

我理解递归的基本概念,并完全理解着名的因子示例是如何工作的。然而,这个我很难绕过我的脑袋。

现在感到无能......

5 个答案:

答案 0 :(得分:9)

在找到基本情况之前,总是有助于分解递归关系。

is_even(2) => return is_odd(1) 
           => return not is_even(1) 
           => return not is_odd(0)
           => return not not is_even(0)
           => return not not True
           => return True            ---- (1)

is_odd(2) => return not is_even(2) 
          => return not True       [from (1)] 
          => return False

通常,从您的递归函数中,很容易发现is_even(n)将返回[not not not ... n times] True,而is_odd(n)将返回[not not not ... n - 1 times] True。因此not s的数量因此最终表达式取决于n(aha!)。那么,这肯定是一种迂回的方式来询问是否

n % 2 == 0

答案 1 :(得分:5)

添加几个print语句,您将看到它正在做什么:

from __future__ import print_function

def is_even(x):
    if x == 0:
        print('True')
        return True
    else:
        return is_odd(x-1)

def is_odd(x):
    print('not', end=' ')
    return not is_even(x)

>>> is_even(5)
not not not not not True
False
>>> is_odd(5)
not not not not not not True
True

答案 2 :(得分:3)

与大多数情况一样,简单地包含print来跟踪执行可能会有所帮助:

def is_even(x):
    print('check if {} is even'.format(x))
    if x == 0:
        return True
    else:
        return is_odd(x-1)

def is_odd(x):
    print('check if {} is odd'.format(x))
    return not is_even(x)

然后在你的情况下:

>>> print(is_even(2))
check if 2 is even
check if 1 is odd
check if 1 is even
check if 0 is odd
check if 0 is even
True

>>> print(is_odd(2))
check if 2 is odd
check if 2 is even
check if 1 is odd
check if 1 is even
check if 0 is odd
check if 0 is even
False

所以基本上它会减少数字,直到它0为止。重点是not次呼叫中累积了多少is_oddnot。如果它是偶数个True s,那么结果将为False,否则为{{1}}。

答案 3 :(得分:2)

这是真的;递归应该在is_even内结束。

当这种情况发生时,你会知道你拥有的号码是0

现在让我们倒退吧。最终状态将通过两种情况实现 - 直接呼叫is_even(0)或来自is_odd(0)的呼叫。在第一种情况下 - 结果都很好。在第二个 - 结果将返回到is_odd函数,否定,因此将是假的 - 给出正确的结果。

现在,这里缺少的部分来了 - 递归:为了达到这种状态,我们需要每次都减少参数,将其传递给相反的函数 - 这正是我们用return is_odd(x-1)得到的。

注意:最终这种递归会导致True返回的值is_even的一系列否定。此链的长度为x,其中x是您的号码,因此奇数或甚至是对应的。

因此,以下代码也会这样做(缺少is_odd好的副作用):

def is_even (x):
    res = True
    while x:
        res = not res
        x -= 1
    return res

答案 4 :(得分:1)

我认为所有其他答案都很棒,但理解问题的最简单方法可能是答案得到多少次而不是#34;不是。每次通过is_odd函数时,都会将no添加到最终答案中。 True将永远返回,但对于偶数,总会有偶数个nots相互抵消,但对于奇数,它们总是有奇数个nots因此返回false。