Не могу понять, как увеличить переменную внутри рекурсивной функции - PullRequest
0 голосов
/ 18 января 2020

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

def collatz(n):
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return n
    else:
        if n % 2 == 0:
            print(n)
            iterations += 1
            return collatz(n // 2)
        if n % 2 == 1:  
            iterations += 1
            print(n)
            return collatz((n * 3) + 1)

Ответы [ 3 ]

1 голос
/ 18 января 2020

Ваша формулировка проблемы немного сбивает с толку, но вы можете попробовать следующий код, если он вам подходит.

def collatz(n):
    iterations = 0
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return n
    elif n % 2 == 0:
        # print(n)
        iterations += 1
        return ("No. of iterations : ", iterations, n//2)
    elif n % 2 == 1:
        iterations += 1
        # print(n)
        return ("No. of iterations : ", iterations,(n * 3) + 1)
1 голос
/ 18 января 2020

Есть несколько вариантов ...

1) Измените сигнатуру функции, включив в нее количество итераций. Таким образом, вы можете передать информацию «вверх по цепочке»

2) Измените область действия num итераций так, чтобы переменная существовала вне функции.

3) Добавить рекурсивную функцию внутри collatz.

подход (1, 3)

def collatz(n):

    def recursion(x, iterations):
        print(f"{iterations}: {x}")
        if x in [0,1,2,4]:
            return x, iterations

        if x % 2 == 0:
            return recursion(x//2, iterations + 1)
        else:
            return recursion((x*3) + 1, iterations + 1)

        return n

    n, steps = recursion(n, 0)

подход (2)

iterations = 0
def collatz(n):
    global iterations

    print(f"{iterations}: {n}")
    if n in [0,1,2,4]:
        return n, iterations

    iterations += 1
    if n % 2 == 0:
        return collatz(n//2)
    else:
       return collatz((n*3) + 1)
1 голос
/ 18 января 2020

Переменная не сохраняется между вызовами функций. Если вы хотите, чтобы между функциями передавалось несколько значений, передайте их в качестве параметра и возвращайте оба.

def collatz(n, iterations):
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return (n, iterations)
    else:
        if n % 2 == 0:
            print(n)
            iterations += 1
            return collatz(n // 2, iterations)
        if n % 2 == 1:  
            iterations += 1
            print(n)
            return collatz((n * 3) + 1, iterations)

Если вам не нравится вызывать вашу функцию, например, collatz(n, 0), тогда используйте это функция-обертка.

def collatz_helper(n, iterations):
        list_terminate = [0, 1, 2, 4]
        if n in list_terminate:
            return (n, iterations)
        else:
            if n % 2 == 0:
                print(n)
                iterations += 1
                return collatz(n // 2, iterations)
            if n % 2 == 1:  
                iterations += 1
                print(n)
                return collatz((n * 3) + 1, iterations)

def collatz(n):
    return collatz_helper(n, 0)
...