2012-03-13 3 views
-1

Я новичок в python, и у меня возникла проблема. Я хочу написать рекурсивную функцию, которая принимает два входа (целые числа) и вычитает вторую из первой, до тех пор, пока первая не станет меньше второй, и вычислит время, из которого он вычитает, прежде чем будет меньше.Функция рекурсии python, которая принимает два входа

Это то, что у меня есть до сих пор, но у меня возникают проблемы с тем, чтобы функция повторяла вычитание второго из первого;

+3

Я не вижу рекурсивного вызова в этой функции. Избавьтесь от цикла while и положите вместо него рекурсивный вызов. –

+0

Здесь нет рекурсии. – Marcin

+0

Я не понимаю, почему это было оценено вниз ... – Rexxo

ответ

0
## naive recursion 
def div(a, b): 
    if (a >= b): 
     return div(a - b, b) + 1 
    else: return 0 

try: 
    print div(5678, 3) 
except Exception as e: 
    print e ## maximum recursion depth exceeded 


## less naive recursion with trampolines 
## see https://gist.github.com/802557 for details/explanations 
def trampoline(f): 
    def _(*args): 
     result = f(*args) 
     while callable(result): 
      result = result() 
     return result 
    return _ 

def div_func(a, b, acc=0): 
    if (a >= b): 
     return lambda: div_func(a - b, b, acc + 1) 
    else: return acc 

div2 = trampoline(div_func) 

## ok 
print div2(5678, 3) 
+0

последние несколько я не понимаю, так как я новичок, однако первый работает отлично. если вы не можете дать краткое объяснение того, как работает код? @ thg435 –

+0

Первый фрагмент такой же, как и другие, уже опубликованные. Второй использует [trampoline] (http://en.wikipedia.org/wiki/Trampoline_%28computers%29), чтобы устранить [рекурсию хвоста] (http://en.wikipedia.org/wiki/Tail_call). Основная идея этого метода заключается в том, что рекурсивная функция, вместо прямого вызова непосредственно, возвращает этот вызов «закрытым» во временную функцию. – georg

1

Вы имеете в виду что-то подобное?

def div(first,second): 
    if (first >= second): 
     return div(first-second,second) + 1 
    else: return 0 

Но вы столкнетесь с проблемой при попытке div(100000,3), например, из-за рекурсии я слишком глубоко. Чтобы избежать этого, вы можете просто сделать:

first/second 
+0

Если вы попробуете мой подход, у вас нет проблем при попытке 'div (100000,3)'! +1 из-за вашего решения 'first/second': да, это просто так (если' first' и 'second' являются' int')! – carla

+0

, но это не рекурсивный @india_dourada. Я, но это более полезно. –

+0

@zenpoy Что, если вместо того, чтобы возвращать число раз, которое было вычтено, я хотел вернуть значение первого после вычитания второго, пока оно меньше первого меньше, как бы я это сделал? –

1

Я считаю, что это должен делать то, что вы хотите:

def div(first, sec): 
    if first >= sec: 
     return div(first - sec, sec) + 1 
    else: 
     return 0 

>>> div(6, 2) 
3 
>>> div(8, 4) 
2 
>>> div(12, 2) 
6 

Вот цепочка вызовов для div(6, 2), который может помочь вам понять, как это работает:

div(6, 2) == 1 + div(4, 2) 
      == 1 + 1 + div(2, 2) 
      == 1 + 1 + 1 + div(0, 2) 
      == 1 + 1 + 1 + 0       
+0

Да, он отлично работает, спасибо. могу ли я кратко объяснить, как это работает? –

0

Это делает то, что вы хотите. Вам не нужна функция if, но while один!

# function: 
def div(a,b): 
    count = 0 
    while a > b: 
     a = a - b 
     count = count + 1 
return count 

# now we'll use the function: 
a = div(565,34) 
b = div(34,565) 

a будет 16, а b будет 0!

+0

извините, это не рекурсивно! – carla

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