2012-12-04 50 views
1

我是新来的Python和学习功能。我遇到以下功能,并在我的智慧结束了解它是如何工作的。在我看来,无论b的价值如何,答案应该总是六个,但事实并非如此。不应该这个Python函数总是返回6吗?

CODE

def mult(a, b): 
    if b == 0: 
     return 0 
    rest = mult(a, b - 1) 
    value = a + rest 
    return value 
print "3 * 2 = ", mult(3, 2) 

我发生了什么

  1. 由于b理解不为0则进入
  2. rest被赋值为3, 1并再次运行该功能
  3. 由于b是1和不等同于0时,它前进到rest
  4. rest的值指定为3, 0和它再次运行功能
  5. 由于b现在零它返回值0
  6. 它然后前进到value具有3 + 3作为a具有3的值和rest具有3即(3,0)
  7. 它返回值6
的值的值

如果我分配mult(3,4),它返回值12.根据我的理解,这是不可能的。显然,我不理解逻辑流程。我究竟做错了什么?

+1

如果你仔细看,它确实'合计(有效范围内的X(B))'但递归... – JBernardo

+0

@JBernardo - 我知道这是递归,但哪里'sum'进来,这是如何工作的。我应该如何阅读逻辑流程? – PeanutsMonkey

+0

我刚刚将算法转换为for循环。尝试向后思考:最后一次迭代返回'0',然后'a',然后'a + a' ...直到'a + a + ... + a'(包裹的数量是'b') – JBernardo

回答

2
  1. mult()被调用3, 2(这是呼叫#1)

  2. 它调用mult()3, 1(这被呼叫#2)

  3. 它调用mult()3, 0(这是呼叫#3)

  4. 返回0(因为b为零)致电#2

  5. 呼叫#2现在返回3 +使得0调用#1

  6. 呼叫#3现在返回3 + 3

基本上,每个调用将会通过递增aa,递归钻研istelf b次。所以,给自己4次加3会产生12。

3

你可以检测你自己的代码,使其更容易地看到发生了什么

def mult(a, b): 
    print "mult(%s, %s)"%(a, b) 
    if b == 0: 
     return 0 
    rest = mult(a, b - 1) 
    value = a + rest 
    print "returns %s"%value 
    return value 
print "3 * 2 = ", mult(3, 4) 

3 * 2 = mult(3, 4) 
mult(3, 3) 
mult(3, 2) 
mult(3, 1) 
mult(3, 0) 
returns 3 
returns 6 
returns 9 
returns 12 
12 

由于递归,打印语句是嵌套

即。 mult(3, 0)返回图3,mult(3, 1)返回图6,等等

4

该函数的基本逻辑是:

让我们(添加a和从b减去1),直到b == 0。它可能更有意义,你是这样的:

def mult(a, b): 
    value = 0 
    while b > 0: 
     b = b - 1 
     value = value + a 
    return value 

只有在一个while循环代替,你的函数一直自称。我设法联系mult他自己,他愿意解释:

嗨,我的名字是mult,我是一个Recurser。递归器是Computer Sciencia中的常见品种 ,我们有一个特殊功能;我们可以自己克隆 。可悲的是我被无法繁衍所诅咒。尽管如此,我仍然希望以我的梦想成为一个倍增器,并且我设法找到了一个方法来做到这一点。方法如下:

当您要求我繁殖(a, b)时,我产生了一个克隆 并询问他(a, b - 1)。克隆重复这个过程直到 产生一个克隆被询问(a0)。当发生这种情况时 (我自己有一行+ b克隆),他回答产生他的 克隆:0。该克隆反过来将a添加到他刚刚被告知的内容(第一次将是0 + a),并将其解答为 克隆在他面前。这个过程重复,直到我得到克隆我产生自己的克隆 。我加a到这个,并将其作为最后的 回答给你!

def mult(a, b): 
    # Should I ask a clone? 
    if b == 0: 
     # No! I reply 0 to my asker. 
     return 0 

    # Yes! I spawn a clone and ask him (a, b - 1) and wait for an answer to 
    # store in 'rest' 
    rest = mult(a, b - 1) 

    # I take the answer and add to it the 'a' I was told 
    value = a + rest 

    # I return the value I calculated to my asker 
    return value 

print "3 * 2 = ", mult(3, 2) # Here someone asks me (3, 2) 
+0

更容易但是想了解一下我的脑袋就想到了递归函数的逻辑流程。永远不知道什么时候我可能会遇到一个复杂的问题 – PeanutsMonkey

+0

我在函数的递归逻辑中添加了一段,我希望这可以让所有的代码都变得可靠 –

2

你的逻辑是正确的,直到子弹5.然后在6跳过一些步骤。 这是一个递归函数。这是比较容易通过在纸上画事件树理解,但让我们先恢复你的逻辑:

MULT(3,4):

1. a = 3, b = 4 
1. rest = mult(3, 3) 
2. a = 3, b = 3 
2. rest = mult(3, 2) 
3. a = 3, b = 2 
3. rest = mult(3, 1) 
4. a = 3, b = 1 
4. rest = mult(3, 0) 
5. a = 3, b = 0 
5. return 0 
4. value = 3 + 0 
4. return 3 
3. value = 3 + 3 
3. return 6 
2. value = 3 + 6 
2. return 9 
1. value = 3 + 9 
1. return 12 

在上面的例子中,一开始每个号码该行表示递归中的步骤。它从第1步开始,直到第5步,然后再返回1,直到第1步再次返回最终答案。

该函数实现了乘法和乘法的概念。例如,3 * 4与三次添加数字'4'相同。

+0

谢谢。我失去了你开始“3 + 0”总和的地方。为什么它在加法中反转,即4,3,2,1? (3,0)意味着'3 * 0'等等,因此'value'是'3 +(3 * 0)' – PeanutsMonkey

+0

我开始value = 3 + 0的部分;达到b = 0,休息时返回0,然后确定value = a + rest; 然后,刚刚计算的值返回到先前的休息,并再次执行value = a + rest;等等。如前所述,递归是棘手的。 试试在YouTube上寻找老师的视频。如果你找到一个他绘制递归树的地方,你会得到它:) – KuramaYoko

1

这是一种直观的看到递归是如何工作的:

COUNTER = 0 

def mult(a, b): 
    global COUNTER 

    COUNTER+=1 
    print " "*COUNTER + "Called with", a,b 

    if b == 0: 
     return 0 
    rest = mult(a, b - 1) 
    value = a + rest 

    COUNTER -= 1 
    print " "*COUNTER, "Value:", value 

    return value 

print "3 * 4 = " 
print mult(3, 4) 

输出

3 * 4 = 
Called with 3 4 
    Called with 3 3 
    Called with 3 2 
    Called with 3 1 
    Called with 3 0 
    Value: 3 
    Value: 6 
    Value: 9 
    Value: 12 
12 

你可以看到调用堆栈如何去一路下跌至底部(B == 0),然后将值返回到顶部。

相关问题