2

これは宿題の問題です。再帰関数を取得しようとしています:

def problem_a(n):
    answer.append(n)
    if n == 1:
        return answer    
    elif n % 2 == 0:
        answer.append(n/2)
    else :
        answer.append(n*3 + 1)
        problem_a(n*3 + 1)

answerリストとして定義されていないため、このコードは明らかに機能しません。ループでも機能しますが、再帰関数を作成したいと思います。リストを入力として使用することもできますが、もっとエレガントなものがあるのではないかと思います。

problem_a(7)出力として与える必要があります:

[7, 22, 11, 34, 17, 52, 26, 13, 40 , 20, 10 ,5 ,16, 8, 4, 2, 1]
4

5 に答える 5

2

ジェネレーターを試すことができます:

def problem_a(n):
    yield n
    if n == 1:
        return
    elif n % 2 == 0:
        x = n / 2
    else:
        x = n * 3 + 1

    for y in problem_a(x):
        yield y

print list(problem_a(7))
于 2013-06-17T11:33:08.590 に答える
2

ローカル変数を定義しanswerて、再帰呼び出しで渡すことができます。

def problem_a(n, answer = None):
    answer = [n] if answer is None else answer
    if n == 1:
        return answer
    elif n % 2 == 0:
        n = n/2
        answer.append(n)
    else:
        n = n*3 + 1
        answer.append(n)
    return problem_a(n, answer)

print problem_a(7)        

出力:

[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
于 2013-06-17T11:26:35.243 に答える
2

これまでに提案された (追加の引数を使用してリストを再帰チェーンに渡す) ソリューションの 1 つの代替ソリューションは、再帰から戻るときに最終的なリストを作成することです。リストを連結するには両方をコピーする必要があるため、これは非常に効率的ではありませんが、機能します。

def problem_a(n):
    if n == 1:
        return [n]
    elif n % 2 == 0:
        return [n] + problem_a(n // 2)
    else:
        return [n] + problem_a(3*n + 1)
于 2013-06-17T11:48:08.757 に答える
1

クロージャーを使用することもできます:

>>> def s():
    ret = []
    def f(n):
        ret.append(n)
        if n % 2 == 0:
            f(int(n/2))
        elif n != 1:
            f(int(n*3 + 1))
        return ret
    return f

>>> s()
<function f at 0x00000000033A5848>
>>> s()(7)
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
于 2013-06-17T13:03:37.360 に答える
1

スケルトン ソリューションに問題があります。n % 2 == 0final と同様にwhen を再帰する必要がありますelse。変数には、引数なしで関数が最初に呼び出されたときにanswer初期化されるように、デフォルト値が与えられます。[]

def problem_a(n, answer=None):
    if answer == None:
        answer = []

    answer.append(n)
    if n == 1:
        return answer    
    elif n % 2 == 0:
        return problem_a(n/2, answer)
    else :
        return problem_a(n*3 + 1, answer)

>>> problem_a(7)
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

編集

コメントによると、変更可能なデフォルト引数を使用することはお勧めできません。他の投稿のようにNoneに設定し、Noneが新しいリストを作成するかどうかを確認してください。これを反映するように回答を変更しました。

元の悪いコードは次のとおりです。

def problem_a(n, answer=[]):
    answer.append(n)
    ...
于 2013-06-17T11:35:23.707 に答える