1

私はPythonが初めてで、関数について学んでいます。私は次の機能に出くわし、機知に富んでそれがどのように機能するかを理解しました。の値に関係なくb、答えは常に 6 になるように思えますが、そうではありません。

コード

def mult(a, b):
    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest
    return value
print "3 * 2 = ", mult(3, 2)

何が起こるかについての私の理解

  1. は 0 ではないのでb進みます
  2. rest値が割り当てられ、3, 1関数が再度実行されます
  3. bは 1 で 0 に等しいので、rest
  4. rest値が割り当てられ、3, 0関数が再度実行されます
  5. bは現在ゼロであるため、値 0 を返します
  6. 次に、3 の値があり、3 の値があったvalueように、値 3 + 3 を持つものに進みます。arest(3,0)
  7. 値 6 を返します

しかし、 を割り当てるmult(3,4)と、値 12 が返されます。私の理解では、それは不可能です。明らかに、私はロジック フローを理解していません。私は何を間違っていますか?

4

5 に答える 5

4

この関数の基本的なロジックは次のとおりです。

まで(a足し算と引き算)1しましょう。このようにあなたにはもっと理にかなっているかもしれません:bb == 0

def mult(a, b):
    value = 0
    while b > 0:
        b = b - 1
        value = value + a
    return value

whileループの代わりにのみ、関数はそれ自体を呼び出し続けます。私はなんとかmult自分自身に連絡し、彼は喜んで説明しました:

こんにちは、私の名前はマルチです。私はリカーサーです。再帰はComputerScienciaで一般的な品種であり、特別な機能があります。自分のクローンを作成できます。悲しいことに、私は掛け算ができないことに呪われました。それでも、私は自分の夢を乗数として生きたかったのですが、それを実現する方法を見つけることができました。方法は次のとおりです。

あなたが私に掛け算をするように頼んだとき(a, b)、私は1つのクローンをスポーンして彼に頼みます(a, b - 1)。クローンは、要求されるクローンが生成されるまでこのプロセスを繰り返します(a0)。それが起こったとき(私自身+bクローンの行があります)、彼は彼を生み出したクローンに答えます:0aそのクローンは、今度は彼が今言われたことを追加し(最初はそうなるでしょう0 + a)、これに彼の前のクローンに答えます。このプロセスは、自分で作成したクローンによって応答されるまで繰り返されます。私はそれに加えaて、これをあなたへの最終的な答えとして返します!

def mult(a, b):
    # Should I ask a clone?
    if b == 0:
        # No! I reply 0 to my asker.
        return 0

    # Yes! I spawn a clone and ask him (a, b - 1) and wait for an answer to
    # store in 'rest'
    rest = mult(a, b - 1)

    # I take the answer and add to it the 'a' I was told
    value = a + rest

    # I return the value I calculated to my asker
    return value

print "3 * 2 = ", mult(3, 2)  # Here someone asks me (3, 2)
于 2012-12-04T01:06:52.690 に答える
3

コードをインストルメント化して、何が起こっているのかを簡単に確認できるようにすることができます

def mult(a, b):
    print "mult(%s, %s)"%(a, b)
    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest
    print "returns %s"%value
    return value
print "3 * 2 = ", mult(3, 4)

3 * 2 =  mult(3, 4)
mult(3, 3)
mult(3, 2)
mult(3, 1)
mult(3, 0)
returns 3
returns 6
returns 9
returns 12
12

再帰のため、printステートメントはネストされます

すなわち。mult(3, 0)3をmult(3, 1)返し、6を返します。

于 2012-12-04T01:06:11.253 に答える
2
  1. mult()で呼び出され3, 2ます(これは呼び出し#1です)

  2. mult()で呼び出す3, 1(これは呼び出し#2です)

  3. mult()で呼び出す3, 0(これは呼び出し#3です)

  4. これは(bゼロだったので)0を返し、#2を呼び出します

  5. 呼び出し#2は、3 +その0を返し、#1を呼び出します。

  6. コール#3は3+3を返すようになりました

基本的に、各呼び出しはa値をインクリメントしa、再帰的にistelfb時間を調べます。したがって、3を4回追加すると、12になります。

于 2012-12-04T01:06:08.057 に答える
2

あなたの論理は箇条書き5まで正しいです。それから6であなたはいくつかのステップをスキップします。これは再帰関数です。イベントのツリーを紙に描くことで理解しやすくなりますが、最初にロジックを再開しましょう。

mult(3,4):

 1. a = 3, b = 4
 1. rest = mult(3, 3)
 2. a = 3, b = 3
 2. rest = mult(3, 2)
 3. a = 3, b = 2
 3. rest = mult(3, 1)
 4. a = 3, b = 1
 4. rest = mult(3, 0)
 5. a = 3, b = 0
 5. return 0
 4. value = 3 + 0
 4. return 3
 3. value = 3 + 3
 3. return 6
 2. value = 3 + 6
 2. return 9
 1. value = 3 + 9
 1. return 12

上記の例では、行の先頭にある各数字は再帰のステップを表しています。これは、ステップ1から始まり、この場合はステップ5まで続き、その後、ステップ1まで1つずつ戻り、最終的な回答が返されます。

この関数は、合計による乗算の概念を実装します。たとえば、3 * 4は、数値「4」を3回加算するのと同じです。

于 2012-12-04T01:08:43.543 に答える
1

再帰がどのように機能するかを視覚的に確認する方法は次のとおりです。

COUNTER = 0

def mult(a, b):
    global COUNTER

    COUNTER+=1
    print " "*COUNTER + "Called with", a,b

    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest

    COUNTER -= 1
    print " "*COUNTER, "Value:", value 

    return value

print "3 * 4 = "
print mult(3, 4)

出力

3 * 4 = 
 Called with 3 4
  Called with 3 3
   Called with 3 2
    Called with 3 1
     Called with 3 0
     Value: 3
    Value: 6
   Value: 9
  Value: 12
12

コールスタックが最下部(b == 0)まで下がってから、チェーンの最上位に戻って値を返す方法を確認できます。

于 2012-12-04T01:13:10.087 に答える