質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • Python 3.x

    7311questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

再帰関数に複数のreturn文がある時、どのreturnが返ってくるのかわからない。

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 234

下記の関数は共に24が返ってくるのはいいのですが、普通の再帰は終了条件でreturn 1で処理しているのに、なぜ1が返ってこないのか、わからないです。
末尾再帰の方は終了条件のaで返ってきているのに・・・・

 階乗を普通の再帰で処理する

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

fact(4)

 階乗を末尾再帰で処理する

def fact(n, a = 1):
    if n == 0: return a
    return fact(n - 1, n * a)

fact(4)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

末尾再帰ではないなら、呼び出し元で計算結果を返しますよね。
順番に追ってみればわかりますよ。

4 
-> 4 * fact(3)
-> 4 * 3 * fact(2)
-> 4 * 3 * 2 * fact(1)
-> 4 * 3 * 2 * 1 * fact(0)
-> 4 * 3 * 2 * 1 * 1

ちなみに末尾再帰はこうなってますよね。

4, 1
-> fact(3, 4 * 1)
-> fact(2, 3 * 4 * 1)
-> fact(1, 2 * 3 * 4 * 1)
-> fact(0, 1 * 2 * 3 * 4 * 1)
-> 1 * 2 * 3 * 4 * 1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/11 11:46

    ご回答、ありがとうございます。
    vscodeデバックのウォッチ式でステップ実行しながら、fact()の変化を見たのですが、よくわからなかったですが、一覧にして書き出していただくとわかりやすいですね。

    キャンセル

0

実際にどうなっているのかわかるよう、コードを整形して、printを多めに入れてみました。

def fact(n):
    print("print1", n)
    if n == 0:
        x = 1  # 追いやすいように分ける(こっちは不要気味、下と合わせるため)
        print("print2", n, x)
        return x
    else:
        x = n * fact(n - 1)  # 追いやすいように分ける
        print("print3", n, x)
        return x

print(fact(4))
""" =>
print1 4
print1 3
print1 2
print1 1
print1 0
print2 0 1
print3 1 1
print3 2 2
print3 3 6
print3 4 24
24
"""

呼び出した子供が返るまで、親は待っている訳です。それだけ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/11 11:50

    ご回答、ありがとうございます。
    printデバックも試してみます。

    キャンセル

-1

4ぐらいなら自分で動作を追いかけていけばいいんでは。
この入力のときにどう判断してなにが帰る、とか紙に書いていけば動作を理解できると思いますぜ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/11 11:48

    ご回答、ありがとうございます。
    一覧にして書き出すのが一番理解しやすいですね

    キャンセル

同じタグがついた質問を見る

  • Python 3.x

    7311questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。