7

Pythonでグローバル変数を使用せずに再帰呼び出しの数を追跡する方法。たとえば、次の関数を変更して呼び出し数を追跡するにはどうすればよいですか?

def f(n):
    if n == 1:
        return 1
    else:
        return n * f(n-1)

print f(5)
4

5 に答える 5

10

これは、グローバルを使用しない巧妙なトリックです。関数自体にカウンターを隠しておくことができます。

def f(n):
    f.count += 1
    if n == 1:
        return 1
    else:
        return n * f(n-1)

その後:

>>> f.count = 0 # initialize the counter
>>> f(5)
120
>>> f.count
5
>>> f(30)
265252859812191058636308480000000L
>>> f.count
35

とにかく、これは「これまでのすべての呼び出し」の場合を処理します。

于 2013-01-25T01:14:24.407 に答える
7

デルナンが言ったように、これまでにすべての呼び出しが必要な場合、グローバルなしでは不可能なので、戻り値を追加するだけで、呼び出しの深さが必要であると想定しています。

def f(n):
    if n == 1:
        return 1,0
    else:
        x, call_depth= f(n-1)
        return n * x, call_depth+1

複数の再帰呼び出しを処理している場合は、max(call_depth1, call_depth2)(最長の呼び出しツリーの深さ)を実行するか、2つ(実際の呼び出しの総数)を合計することができます。

于 2013-01-25T01:12:51.593 に答える
6

このメソッドは、関数が実行された合計回数を示します。

def f(n):
    if hasattr(f,"count"):
        f.count += 1
    else:
        f.count = 1
    if n == 1:
        return 1
    else:
        return n * f(n-1)
于 2013-01-25T01:33:15.137 に答える
4

これは、グローバル変数の代わりにスタックを使用する方法です。示されているように、関数がそれ自体に対して行った再帰呼び出しの数だけでなく、最初の呼び出しを含む関数への呼び出しの数を集計します。これを行うには、をステートメントncalls += 1の先頭に移動します。else

def f(n, ncalls=0):
    ncalls += 1
    if n == 1:
        return 1, ncalls
    else:
        res, ncalls = f(n-1, ncalls)
        return n * res, ncalls

for n in xrange(1, 6):
    print 'f({}): {:4d} ({} calls)'.format(n, *f(n))

出力:

f(1):    1 (1 calls)
f(2):    2 (2 calls)
f(3):    6 (3 calls)
f(4):   24 (4 calls)
f(5):  120 (5 calls)
于 2013-01-25T03:06:17.773 に答える
0

呼び出しの数を保持するための引数を追加することができます(可変のものである必要があります)。ここで、関数の開始時に増分されます。

于 2013-01-25T01:11:13.137 に答える