2017-01-30 11 views
0

2つの数値を追加したいとしますが、1だけインクリメントとデクリメントできます。この問題は、再帰の使用を含む多くの方法で解決できます。 mとnを追加すると、次のPython定義を使用できます。再帰で混乱している別のコーダー

def slowAdd(m, n): 
    if n == 0: 
     return m 
    else: 
     return 1 + slowAdd(m, n-1) 

これは本当に混乱しています。誰かが最終的なリターンコールがどのように動作するか説明できますか? Pythonは定義された関数の値を1に追加するとき、その値をどのように解釈しますか?

+1

"定義された関数の値"ではなく、*関数呼び出し*の戻り値*です。それはあなたを助けますか? –

+0

'slowAdd(m、n-1)'によって*返されたものを追加しています。したがって、 'def f(n):return 8 - n'を実行し、' 1 + f(1) 'を実行した場合、8を得ます。 –

+0

再帰に関するWikipediaのエントリを読んでください。 – Barmar

答えて

2
のように書くことができ、また、あなたがループ内のprint文を追加することができますし、何が起こっているか見ることができるだろう

さて、超シンプルな関数を見てみましょう。私はx = super_simple_function()を行う際

def super_simple_function(): 
    return 0 

はどうなりますか?関数の戻り値値はゼロですのでです

>>> x = super_simple_function() 
>>> x 
0 

。したがって関数オブジェクトがあり、呼び出されると値が返されます(返されます)。

あなたの再帰関数を行ごとに見てみましょう。 2と3を引数として渡したとしましょう(slowAdd(2, 3))。

1行目:def slowAdd(m, n)
これは、最初の引数がmと第二、nに等しいことを意味します。従って、我々の場合、m = 2n = 3

2行目:if n == 0
これはn equals to 0トリガ条件です。さて、今はn = 3なので、この条件は無視されます。

3行目:return m
nは0に等しい、このラインは、今では無視されていませんので。私たちはそれに戻ってきます。

4行& 5:else: return 1 + slowAdd(m, n-1)
ここで起こって三つのことがあります。

  1. 戻り値はslowAdd(m, n-1)です。
  2. 戻り値に1を加えます。
  3. #2から合計を返します。

この関数は、#1のために再帰的と呼ばれます。あなたが想像することができるように、この関数はn == 0までそれ自身を呼び出し続けます。その時点で1 + slowAdd(m, n-1)の代わりにmを返します。

1st recursion: return 1 + slowAdd(2, 2) 
2nd recursion: return 1 + slowAdd(2, 1) 
3rd recursion: return 1 + slowAdd(2,0) 
4th recursion: return 2   # n is finally 0! 
:我々はすべての再帰に1による nをデクリメントしているためと、私たちは nが0

に最終的に等しいので、これは我々が引数として(2, 3)を渡すときに、関数が何をしているのか、基本的であるだろうことを確かに知って

これは2 + 1 + 1 + 1 = 5になります。

4

"slowAdd(m、n-1)"を正しいリターン式(n = 0の場合は "m"、それ以外の場合は "1 + slowAdd(m、n-1)"を代入する) 。

例:nの戻り通話中

slowAdd(5,3) 
1 + slowAdd(5, 3-1) 
1 + (1 + slowAdd(5, 2-1)) 
1 + (1 + (1 + slowAdd(5, 1-1))) 
1 + (1 + (1 + 5))) // n=0 
1

= 0、関数は、n-1番目の値に1を加算し、再び自分自身を呼び出します。私はこれをイラストによってより良く説明するだろう。 (slowAdd(1,3):)

slowAdd(1,3) 
returns 1+slowAdd(1,2) 
      returns 1+slowAdd(1,1) 
        returns 1+slowAdd(1,0) 
           returns 0 

だから何が起こっていることである:あなたと呼ばれる機能で何が起こっているかで、次の

1+3 
=1+(1+2) 
=1+(1+(1+1)) 
=1+(1+(1+(1+0))) 
1

我々はそこにプログラムを実行する際には、我々は、スタックと呼んでいるものです関数(A)が別の関数(B)を呼び出すとき実行の

プログラムは、機能(B)の終了時に機能(A)の実行を継続できるように、機能Aのコンテキストを実行スタックに保存する。

コンテキストは、すべて関数のローカル変数と残りの命令です。

slowAdd(1,9)を呼び出す前にこのslowAdd(1,9)のような関数を呼び出すと、プログラムはコンテキストを保存してn = 1の現在の値とmの現在の値= 9、最後の命令は1 + slowAdd(0,9)です。slowAdd(0,9)を呼び出します。 slowAdd(0,9)は9を返し、プログラムは関数の最初の呼び出しに戻ります。コンテキストを復元し、呼び出しを戻り値に置き換えます。 1 + slowAdd(0,9)は、1 + 9

1

ラインif n == 0:if not n:

def slowAdd(m, n): 
    if not n: return m 
    else: 
     print('1 + ({}, {})'.format(m, n)) 
     return 1 + slowAdd(m, n-1) 


print(slowAdd(5,5)) 
1 + (5, 5) 
1 + (5, 4) 
1 + (5, 3) 
1 + (5, 2) 
1 + (5, 1) 
10 
関連する問題