2012-01-02 58 views
5

我正在阅读获得“反转”徽章的答案,我发现一个关于递归的问题,即OP没有打扰他们做许多家庭作业。除了一些真正有趣的答案之外,@ machielo在python中发布了an answer,我必须在我的机器上运行才能掌握它。我仍然不理解它。我不明白这是递归使用

def recursive(x): 
    if x > 10: 
     print recursive(x/10) 
    return x%10 

>>> recursive(2678) 
2 
6 
7 
8 

我尝试了我的第一个猜测,但我知道这是错

>>> 2678/10 
267 
>>> 267/10 
26 
>>> 26/10 
2 
>>> 2%10 
2 

好吧......这是两个。这是如何评估x中其他数字的输出?

编辑

这是print声明,我不明白这里。我修改了代码,例如:

>>> def recursive(x): 
if x > 10: 
    print x 
    print recursive(x/10) 
return x%10 

>>> #I will comment the interpreter session here... 
>>> recursive(2345) 
2345 # first feed in...print the raw number `x` 
234 # 2345/10 does equal 234...the 5 is being held back somewhere... 
23 # and each pass through the recursive loop removes the last digit... 
2 # but where was it being stored at, so that each evaluation of 
3 # x > 10 finally started returning False 
4 # and returns the number, exiting the function 
5 # ... 

我在想,在每个贯穿,调用print recursive(x/10)创建一个新的函数对象,每个都有它自己的全新的基本情况和输入法...

另一个提示,任何人?

FINALLY

感谢大家。我觉得我现在明白了......这个技巧并不是print,因为它是x%102345%10 == 5 ...

>>> def recursive(x): 
print "Raw `x`:", x 
if x > 10: 
    print "Recurse `x`:", x 
    print recursive(x/10) 
print "Last `x`:", x  
return x%10 

>>> recursive(2345) 
Raw `x`: 2345 
Recurse `x`: 2345 
Raw `x`: 234 
Recurse `x`: 234 
Raw `x`: 23 
Recurse `x`: 23 
Raw `x`: 2 
Last `x`: 2 
2 
Last `x`: 23 
3 
Last `x`: 234 
4 
Last `x`: 2345 
5 

此外,信贷对谁进去,并更新了最初的回答是I previously linked to ...我要给予好评您的评论:

>>> def recursive(x): 
if x >= 10: 
    print recursive(x/10)  
return x%10 
+0

我想我不完全理解这个问题。 “x'中的每个数字”是什么意思? – 2012-01-02 23:04:52

+0

我不想用我所有的错误猜测**来浑浊我的问题,但** ...用'return recursive(x/10)'替换'print recursive(x/10)'将会把基本情况推到递归的第一遍。 – Droogans 2012-01-02 23:06:44

+0

您的示例不会为我生成该输出 – joaquin 2012-01-02 23:08:43

回答

11

我认为,加入少量print声明它是真正有帮助的:

def recursive(x): 
    print '[start] recursive({0})'.format(x) 
    if x > 10: 
    print recursive(x/10) 
    print '[return] recursive({0}) = {1}'.format(x, x%10) 
    return x%10 

print recursive(2678) 

输出是:

[start] recursive(2678) 
[start] recursive(267) 
[start] recursive(26) 
[start] recursive(2) 
[return] recursive(2) = 2 
2 
[return] recursive(26) = 6 
6 
[return] recursive(267) = 7 
7 
[return] recursive(2678) = 8 
8 
+0

很好的答案,真的 – joaquin 2012-01-02 23:21:38

+0

@joaquin谢谢,我很感激。 – jcollado 2012-01-02 23:32:03

+0

我复制了你的格式并稍微修改了一下,这样我就可以强制自己从内存中构建它。好例子! – Droogans 2012-01-02 23:56:47

3

此函数打印出的数字的数字。

它的工作原理是这样的:

def recursive(x): 
    if x > 10: 
    # Divide x by 10 and round down. This chops off the last decimal place. 
    # Now feed that new x without the last decimal place back into recursive() 

    # return x's last digit 

基本上,它不会print任何东西,直到x是一个单一的数字。

您感到困惑的部分可能是为什么它按顺序打印出每个小数位。发生这种情况是因为在函数递归时,父函数仍在运行。

只需尝试并展开该单个号码的代码即可。


编辑:我混淆自己为好。

代码调用之前returnprint,这意味着当最后水平递归结束,第二个到最后打印出的第一位。下一层也是如此。

+0

好的@Blender,我会写出我模仿堆栈图的可怕尝试。 – Droogans 2012-01-02 23:10:35

5

通过您的例子伪步进(破折号的数字表示递归深度):

-call recursive(2678) 
--2678 > 10, call recursive(267) 
---267 > 10, call recursive(26) 
----26 > 10, call recursive(2) 
-----return 2%10 (which is 2) 
----print 2, then return 26 % 10 (which is 6) 
---print 6, then return 267 % 10 (which is 7) 
--print 7, then return 2678 % 10 (which is 8) 
-return 8 
+0

所以你说'print'语句直到递归循环的后期才被评估,即使如此......它实际上并不显示结果?这是你打印2,然后返回26%10'的意思吗?你的最后一行是'return 8',这就是我为什么这样想的原因。 – Droogans 2012-01-02 23:31:26

+0

@Droogans我认为这是正确的。最后8是由控制台打印的 – joaquin 2012-01-02 23:34:36

+0

这不是它没有评估。 print语句不能被解析,因为它不断地递归调用方法。直到它在底部返回一个值,这些值才能被解析,因此递归可以被看作是冒泡的答案。 – Jordan 2012-01-02 23:37:29

1

在考虑递归时记住调用堆栈。递归调用是推动所有recursive()函数调用到任何打印之前,所以你最终与堆栈上的堆栈

recursive(2) # end condition is met so returns 2%10 
recursive(26) 
recursive(267) 
recursive(2678) # the initial call 

一旦达到2%,结束条件10返回到以前的(2)函数的打印语句并打印,那么该函数返回26%10(6),并且这一过程一直持续到堆栈上的所有递归函数调用都返回。结果是这一系列的打印呼叫:

print 2 
print 6 
print 7 
8 

8实际上没有打印;它只是从翻译中返回而已。如果你想确保它打印在例如python脚本中,你可以打电话print recursive(2678)