2013-06-15 2 views
7

Я пытаюсь написать рекурсивную функцию, которая печатает от 0 до n, но я понятия не имею, как это сделать. Я случайно сделал один, который печатает от п до 0 хотя:Рекурсивная функция python, которая печатает от 0 до n?

def countdown(n): 
    print(n) 
    if n == 0: 
     return 0 
    return countdown(n - 1) 

Я не знаю, если это помогает или нет, может быть, я могу изменить что-то из кода, чтобы сделать его от 0 до п?

ответ

6

Вы почти получили!вот фиксированная, упрощенная версия:

def countup(n): 
    if n >= 0: 
     countup(n - 1) 
     print(n) 

Обратите внимание, что:

  • Вы не должны ничего возвращать из рекурсивной функции, которая печатает только дорожит
  • Для печати в порядке возрастания, то print заявление должно быть размещено после рекурсивный звонок
  • Рекурсия завершается, когда n < 0, учитывая, что мы только печатаем, ничего не остается сделать terwards и это нормально, чтобы вернуть None (возвращение значение по умолчанию в Python)

UPDATE

кажется, что написание рекурсивного решения хвоста все бушует вокруг здесь :) Ну хорошо, вот мой выстрел на него , упрощенная и хвостовая рекурсия версия @ AndyHayden задумки - используя хвост вызова оптимизации декоратора recipe:

@tail_call_optimized 
def countup(N, n=0): 
    print(n) 
    if n < N: 
     countup(N, n + 1) 

в любом случае, это работает, как ожидалось:

countup(5) 
=> 0 
    1 
    2 
    3 
    4 
    5 
+1

Не знал об этом декораторе, как здорово! –

3

Вы можете заменить 0 и п, а + с - чтобы сделать вашу рекурсивную функцию обратного отсчета времени на рекурсивный Countup:

def countup(N, n=0): 
    print(n) 
    if n == N: 
     return 
    return countup(N, n + 1) 

И называют его следующим образом:

countup(3) 

@JFSebastian указывает, что этот алгоритм имеет преимущество O (1), а не O (n), как обсуждалось в этом excellent article о различии между линейной и итеративной рекурсией, если используется с декоратором @tail_call_optimized.

+0

Ого, подождите, что? – Makoto

+0

OP запрашивает рекурсивную функцию UP? Нет? –

+0

печать от 0 до n ... –

10

Вы здесь около 99%.

Подумайте о своем базовом корпусе и вашем рекурсивном шаге - когда вы нажмете 0, что вы хотите сделать? Когда вы все еще работаете от n, что вы хотите?

Если вы измените порядок печати значения, вы достигнете желаемого результата.

def countdown(n): 
    if n != 0: 
     countdown(n-1) 
    print(n) 

Причина этого в том, что рекурсивные вызовы идут в стек вызовов. Когда вы нажимаете вызовы на стек, в то время как ваш конечный случай не выполняется, вы будете продолжать добавлять больше вызовов, пока не достигнете базового футляра n == 0, а затем вы начнете печатать только значения.

Другие вызовы затем попадают в оператор печати, так как их выполнение вернулось к строке после условного.

Таким образом, вызов стек выглядит примерно так:

countdown(5) 
    countdown(4) 
     countdown(3) 
      countdown(2) 
       countdown(1) 
        countdown(0) 
        print(0) 
       print(1) 
      print(2) 
     print(3) 
    print(4) 
print(5) 
+0

И это так. Это печатает 0 1 2 3 4 5, все на отдельных строках. Если бы это было отсчет, это было бы печать 5 4 3 2 1 0, на отдельных строках. – Makoto

+2

Для вашего решения требуется O (n) память. @ Andy Hayden предоставляет способ сделать это в O (1) памяти (просто добавьте декоратор tail_call). [Посмотрите на две фотографии в SICP] (http://mitpress.mit.edu/sicp/full-text/sicp/book/node15.html), чтобы понять разницу (ваш ответ - первое изображение) – jfs

+1

@JFSebastian I не вижу, как решение Andy использует меньше памяти. Оба решения будут использовать фреймы 'n', но у Andy's есть две локальные переменные на кадр, тогда как у этого есть только один. – Aya

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