2009-08-17 57 views
1

我碰到了一个小的递归代码。我已经打印输出,它的打印效果很好,但是当我尝试将计数器实际计入我的答案时,它会给我提取错误。python scooping和递归

total = 0 
def foo(me, t): 
    if t<0: 
     return 
    if t==0: 
     total = total+1 
     return 
    for i in range(1, me+1): 
     total = total+1 
     return foo(i, t-i) 

它说,分配前引用了局部变量,那么,我想是指在第一线总....它不是全局变量,我曾尝试使用全局很好,但徒劳无功。

这是纯粹的舀问题,任何想法?

+1

这个问题你的意思是范围界定? – Svante 2009-08-17 07:50:16

+2

顺便说一句,你的“for”循环只会在每个递归中执行一次,而'i'将始终为1. – Svante 2009-08-17 07:54:43

回答

1

您忘记确保在您的功能中将总数设置为全局。你说过:“我试图用全球化,但徒劳无益。”但是当我尝试它下面不抛出任何错误:正如其他人所提到

total = 0 
def foo(me, t): 
    global total 
    if t<0: 
     return 
    if t==0: 
     total = total+1 
     return 
    for i in range(1, me+1): 
     total = total+1 
     return foo(i, t-i) 
+0

它不会抛出错误,但回答将不正确。例如如果你尝试foo(99,100),你会得到101,这是不正确的。但如果您发出完整的申报和使用情况并开始打印,则会打印正确的次数。 – hasanatkazmi 2009-08-17 08:02:16

+0

这个线程可能会详细说明我想说的: http://mail.python.org/pipermail/python-list/2001-September/104562.html – hasanatkazmi 2009-08-17 08:06:05

+2

你的分析是不正确的:101是正确的答案。每次击中第7行或第10行时,您总共添加一个;后者是你在[1,100]中击中t,而在t = 0时是前者。 “全球化”不是问题。 – 2009-08-17 08:29:44

2

,你需要完全的global声明。另外,正如Svante所指出的那样,由于i总是1,所以for循环是不必要的。所以,你的代码的等效版本:

total = 0 
def foo(me, t): 
    global total 
    if t < 0: 
     return 
    total = total + 1 
    if t == 0: 
     return 
    return foo(1, t-1) 

foo(99, 100) 
print total 

它应该是更容易地看到,FOO(99,100)的确会因为101你基本上倒计时从100到0。我不当然,为什么你认为不然?

1

我不知道你真的知道你正在尝试做的... (至少如果你说​​,加上全球关键字给出了不正确的结果,但沉默的错误)

需要声明的“全球总”如果你要尝试引用总(你正在做的)

(什么是你当你执行FOO(99,100)预期?)

也许你的边界条件错了?

“事业的参数(99,100)

  1. foo将跳过两个if语句
  2. 环下面的循环:

    for i in range(1, 100): 
    total += 1 
    return foo(i, 100-i) 

这实际上相当于


    else: 
    total += 1 
    return foo(1, 99) 

(像斯万说的话)的基础上

你的两个if条件 富(1,99)将正确生成总+ = 100

(99次将执行你的“其他”声明使共有100个,最后将达到牛逼== 0和执行最后的决赛中,如果它会推动总到你的“不正确” 101)

,你也应该使用ELIF你的第二个案例

1

作为一般性的adv冰,递归应该总是使用返回值,而不是全局变量。递归已经有了它自己的复杂负担,增加了副作用,而不清晰的接口会使它变得更糟。

你应该尝试在此线的东西:

def foo(me, t): 
    if t<0: 
     return 0 
    if t==0: 
     return foo(me, t+1) 
    return foo(me-1, t) 
    for i in range(1, me+1): 
     tot = foo(i, t-i) 
    return tot 

注意:此代码是,它将解决您的问题,它会自身甚至工作;我只是想给出一种关于如何设计易于管理的递归的想法。

0

感谢人们,谢谢youarf,Liffredo。 我错了,我没有注意到我在加入东西之前回来了,循环只运行了一次,我修复了代码。它是这样的:

def foo(me, t): 
    if t<0: 
     return 0 
    if t==0: 
     return 1 
    toreturn = 0 
    for i in range(1, me+1): 
     toreturn = toreturn + foo(i, t-i) 
    return toreturn 

这个片段是在http://projecteuler.net/index.php?section=problems&id=76