2009-08-17 2 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

+2

Ваш цикл «for» будет выполняться только один раз в каждой рекурсии, между прочим, и 'i' всегда будет 1. – Svante

ответ

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

+0

В этой теме может быть рассказано, что я хочу сказать: http://mail.python.org/pipermail/python-list/2001-September/104562.html – hasanatkazmi

+2

Ваш анализ некорректен: 101 - правильный ответ. Вы добавляете его к сумме каждый раз, когда вы нажимаете строку 7 или 10; последнее вы попадаете на t в [1100], первое при t = 0. «Глобальный» не является проблемой. –

2

Как уже отмечалось другими, вам необходимо global заявление для всего. Кроме того, как отметил Сванте, цикл for не нужен, поскольку кодируется с i всегда 1. Таким образом, с эквивалентной версии кода:

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 пропустит два, если заявления
  2. цикл в следующем цикле:

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

, который на самом деле эквивалентно


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

(как Сванте говорил)

на основе вашего два, если условия Foo (1,99) будет правильно генерировать общий + = 100

(99 раз он будет выполнять ваши «еще» заявление принося общие до 100, а затем, наконец, он достигнет т == 0 и выполнить последний финал, если, где он будет толкать общий для вашего «неправильного» 101)

вы также должны использовать Элиф для второго случая

1

Как общий совет лед, рекурсия должна всегда использовать возвращаемые значения, а не глобальные переменные. Рекурсия уже имеет собственную нагрузку сложности, увеличивая ее с помощью побочных эффектов, а не понятные интерфейсы сделают ее еще хуже.

Вы должны попробовать что-то в строках этого:

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

Спасибо, спасибо, ребята, 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

Смежные вопросы