-3

私はpythonが初めてです。このコードを説明できますか?

def factorial(n):
    if n == 0:
        return 1
    return n*factorial(n-1)

>>>print factorial(5)
>>>120

ありがとうございました!

4

1 に答える 1

4
def factorial(n):            # define a function, receiving a value 'n'
    if n == 0:               # if n is 0, then...
        return 1             #    return the result 1 to the calling code (done!)
    return n*factorial(n-1)  # otherwise return n times the result of calling
                             #  this function (factorial) with the lower value

>>>print factorial(5)

# factorial(5): 5 != 0, so return 5 * factorial(4)
#   factorial(4): 4 != 0 ...
#     ...
#           factorial(0) = 1 returns to factorial(1) call:
#         factorial(1) = 1 * 1 = 1, returns to factorial(2) call:
#       factorial(2) = 2 * 1 = 2
#     factorial(3) = 3 * 2 = 6
#   factorial(4) = 4 * 6 = 24
# factorial(5) = 5 * 24 = 120, return this

>>>120

これはrecursionと呼ばれ、オンラインで優れた説明を見つけることができます。factorialこれは従うべき手順であることを思い出してください。factorial(n-1) 式を見ると、python は n-1 を計算してから、この値でここへの新たな呼び出しを開始します。その結果、各呼び出しは、factorial最終的に 0 に達するまで別の呼び出しを行い、スタックを最も外側の呼び出しに戻し始めることができます。これを自分で解決しようとすると想像してみてください。同じようなことをしていることに気付くでしょう:

(5 * (4 * (3 * (2 * (1 * 1)))))

内側のブラケットの値がわかるまで、最も外側のブラケットを完成させることはできません。

ただし、コードには重大な欠陥があることに注意してください。n-1-1-1-1-1 などが 0 に到達しない場合 (たとえば、n=1.1 の場合)、return 1行に到達することはなく、到達することもありません。うさぎの穴の底。実際には、各呼び出しがスタック上で少し多くのスペースを占有し、最終的には不足するため、スタック オーバーフロー エラーが発生する可能性があります。

さらに詳しく調べるには、末尾呼び出しの再帰 (これはその例です) と、再帰呼び出しが return ステートメント (末尾) にある場合にコンパイラがスタック オーバーフローの問題を回避する方法について学びます。

于 2012-11-16T15:17:04.350 に答える