No.2ベストアンサー
- 回答日時:
ええと、もう一つ書き方お教えしましょう。
多分元の書かれたコード見る限り、多分こっちの方が分かりやすいかな、と思います。
文字通り「再帰関数への変換」です。
ちょっとコメント合わせますが、こう言う思考回路で書いてるんじゃないか、って思います。
def foo(n, m):
sum = 0 # 1. アキュムレータ(累積器)を 0 とする
while m > 0: # 2. m(カウンタ) が 0 以上の場合
sum = sum + n # a. アキュムレータに n を加算して
m = m -1 # b. カウンタ から 1 を引く
return sum # 3. それ以外の時にはアキュムレータを返す
ロジックはこの通りですよね。非常に明解です。
ちなみに、アキュムレータとは、このテの繰り返し計算をする際に、加算等の結果を記憶する変数の事を指します。このコードでは sum がそれに当たりますね。
また、m は繰り返し回数を指定するカウンタです。
実はこのロジック殆どそのままで再帰を書くことが出来ます。
コツは以下の通り。
☆ アキュムレータも関数の引数にしてしまう
これが最大のポイントです。つまり関数の書き始めは
def foo(n, m, sum):
にしてしまうんです。これが最大のコツです。
そうすると、
def foo(n, m, sum):
m(カウンタ) が 0 以上の場合:
アキュムレータに n を加算してカウンタ から 1 を引く
それ以外の時にはアキュムレータを返す
と言う形が見えてきますね。殆ど元のコードが意図する事と同じです。
もうちょっと言うと
def foo(n, m, sum):
if m > 0:
アキュムレータに n を加算してカウンタ から 1 を引く
else:
return sum
が形として決まるわけですが、平たく言うと、まだ平仮名で残ってる部分が再帰部分になります。
内容は全く元コードと同じなんですが、大元関数のfooを呼び出すところが違ってるわけですね。
んで、再帰のもう一つのポイントは
☆ 元のコードで書いてた部分を引数内の処理にして完結してしまう。
です。コードなんて書かなくて良い、ただ、引数内に計算式をぶちこんじゃえ。こう言うわけです。
つまり、
def foo(n, m, sum):
if m > 0:
return foo(n, m - 1, sum + n) # 引数内に注目!
else:
return sum
3行目を見てみればわかりますが、元のコードの
・アキュムレータに n を加算する。
・カウンタ から 1 を引く。
って2つの作業を foo の引数内で処理してる事が分かるでしょう。
これで終わり、です。
ちょっと実行してみましょうか。
>>> foo(1, 10, 0)
10
キチンと動きますね。
オリジナルのコードにあった
sum = 0 # 1. アキュムレータ(累積器)を 0 とする
ってのが消えて、外部から第3引数として0を与える、って事だけが違いますね。
ただ、一々第3引数に0を与える、分かりきってるのにメンド臭い、って場合は、Pythonではデフォルト引数ってのが使えるんで、コードの第1行目を次のように書き換えれば
def foo(n, m, sum = 0): # ここの第3引数を sum = 0 とする
if m > 0:
return foo(n, m - 1, sum + n)
else:
return sum
第3引数を与えなくても問題無く動きます。
>>> foo(2, 10)
20
なお、この形式の再帰を末尾再帰(tail-call-recurcive)と呼びます。
No.1
- 回答日時:
同じ内容なら
def foo(n,m):
if m < 0:
retern 0
else:
return n + foo(n,m-1)
です。
全角空白2つを半角空白4つでインデントし直してください。
この回答への補足
yelser 様
ありがとうございます。
shellでやると次の結果がでます、
>>> def foo(n, m):
... if m < 0:
... return 0
... else:
... return n + foo(n, m-1)
...
>>> foo(2, 10)
22
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- Excel(エクセル) A列が指定数値以上になったらD列の計算式を変更 3 2022/07/11 11:03
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- Excel(エクセル) VBA SUM関数を入力したい 6 2022/08/20 20:10
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- Visual Basic(VBA) 最終列の右へSUM関数を作成するため下記コードを実行しましたが、最終列「10月28日」が上書きされて 3 2022/12/05 20:32
- Excel(エクセル) エクセルの数式を等間隔にオートフィルできるやり方を教えていただきたいです。 実際の作業↓ A3セルに 7 2023/06/05 19:04
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
pythonにてseleniumを使うも、...
-
Exel VBA 別ブックから該当デ...
-
chatgptでつくってもらったコー...
-
ExcelのVBAコードについて教え...
-
パイソンプログラム
-
フィルターかけた後、重複を除...
-
1、Rstudioで回帰直線を求める...
-
vb6.0の実行時エラー'3075'につ...
-
Gitのクローンについて
-
特定行の背景色を変えたいのですが
-
Excel VBA素人です。VBAで図形...
-
コンパイルエラー 変数が定義...
-
access2003 クエリSQL文に...
-
楽観的排他処理のためViewState...
-
プレースホルダー
-
CFormViewでの印刷について
-
変数名「cur」について
-
文字コードについて
-
Excel VBAについて
-
SQL
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
フィルターかけた後、重複を除...
-
access2003 クエリSQL文に...
-
1日に1人がこなせるプログラム...
-
Exel VBA 別ブックから該当デ...
-
pythonにてseleniumを使うも、...
-
ExcelのVBAコードについて教え...
-
ExcelのVBAコードについて教え...
-
chatgptでつくってもらったコー...
-
欠番の抽出について
-
JANコードとPOSコードは同じ?
-
JavaScriptの定数名が取り消し...
-
1、Rstudioで回帰直線を求める...
-
特定行の背景色を変えたいのですが
-
変数名「cur」について
-
PreviewKeyDownイベントが2回...
-
将来AIが進歩してくるにつれて...
-
ACCESSユニオンクエリでORDER B...
-
COBOLの文法
-
VBAでファイルオープン後にコー...
-
Nullの使い方が不正です。
おすすめ情報