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

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

新規登録して質問してみよう
ただいま回答率
85.48%
ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2504閲覧

pythonの再帰呼び出しの使い方に関して

studioperon

総合スコア1

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/02 10:58

編集2021/02/02 11:47

大学のプログラミングの講義で、pythonで線形リストを扱っています。

class Cell:
info : Any
next : Any
このように、info でリストの要素を、next で次のセルを指すポインタを表現していて、
例えば[-27,823,54]からなる線形リストを

Cell(-27, Cell(823, Cell(54, None)))

のように構成しています。
次に数学の話ですが、以下はすべて整数範囲の話です。
あるn次元多項式f(x)について、
f(x)=a_0+a_1 x+a_2 x^2+⋯+a_(n-1) x^(n-1)+a_n x^n
の係数が、実装した線形リストの要素として表されています。
Cell(a_0, Cell(a_1, Cell(a_2, Cell( ...Cell(a_n-1, Cell(a_n, None)...))))
ということです。

話がややこしくて申し訳ないのですが、
ここで考えたいのが、この多項式f(x)についてx=bのときの解についてです。
これを求めるプログラムを、再帰関数で実装したいのです。

ホーナー法という多項式の計算法を、再帰性を利用して表現したく、
a_0 + b*(a_1 +b*(a_2 + ...+b*(a_n-1 + b*a_n))...)という数式を考えていて、
カッコで囲まれた部分に再帰性を使えないかと思っています。
いろいろ試しているのですが、うまくいかないです。

おそらく、関数の引数のリストのポインタが、Cell丸ごとではなく要素を直接指し示す、
もしくは要素だけ再帰呼び出しをかける、などできたらうまくいくのではないか、と素人ながら考えているのですが、何かアイデアをいただけたらと思って投稿させていただきました。

追記
TypeError が出たのですが
これは、「関数の呼び出し部分が整数値でない」という意味であっていますか?

少し調べましたがエラーメッセージを正しく解釈できているかわかりません。
また、これに対する解決案も何かありましたらよろしくお願いします。

発生している問題・エラーメッセージ

Traceback (most recent call last):

File "<stdin>", line 1, in <module>
File "main.py", line 28, in eval_poly
return a * eval_poly(p.next, a) + p.info
File "main.py", line 28, in eval_poly
return a * eval_poly(p.next, a) + p.info
File "main.py", line 28, in eval_poly
return a * eval_poly(p.next, a) + p.info
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'

該当のソースコード

python

1def eval_poly(p,a): 2 if p is None: 3 return None 4 else: 5 return a * eval_poly(p.next, a) + p.info 6

試したこと

python

1def eval_poly(p,b): 2 return eval_poly(p.next, b) * b + p.info

というコードでは、
AttributeError: 'NoneType' object has no attribute 'next'
のメッセージが出ました。これは再帰呼び出しの停止条件がなかったためだと
ご指摘をいただきました。

補足情報(FW/ツールのバージョンなど)

real.it でソースを書いています。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

python

1def eval_poly(p,a): 2 if p is None: 3 return None 4 else: 5 return a * eval_poly(p.next, a) + p.info

これだとp.next=Noneの場合、上の最後の式は以下のような計算をすることになります。

python

1 return a * None + p.info

なので、TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'と言われています。以下みたいな感じでちゃんと終了条件を考慮しないといけません。

python

1def eval_poly(p,a): 2 if p is None: 3 return None 4  elif p.next is None: 5 return p.info 6 else: 7 return a * eval_poly(p.next, a) + p.info

投稿2021/02/02 12:03

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

studioperon

2021/02/02 12:24

教えていただいた通りのプログラムできちんと動きました。 他の方々からもご指摘していただいたように、きちんと終了条件を考える必要がありました。 エラーの内容と原因まで詳しく教えていただき勉強になりました。ありがとうございました。
guest

0

再帰関数を作るには、
・停止の条件
・次の処理の呼び出し
の2つが必要です。

python

1def eval_poly(p,b): 2 return eval_poly(p.next, b) * b + p.info

この関数には、次の処理の呼び出しはありますが、停止条件がありません。
なので、最後のセル 「Cell(a_n, None)」に到達しているのに、Noneのnextを 参照しようとしてエラになっています。

nextがNullだったらxxxを返すという処理を追加すれば再帰処理そのものは動くようになると思いますよ。

投稿2021/02/02 11:14

TakaiY

総合スコア12743

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

アルゴリズムを正しく把握できているかは自信がありませんが、とりあえず再帰を書くのであれば終了条件は何らかの形で決める必要があります。

リストの末尾までたどってpNoneになったときの処理ですね。0を返すことにするor次でNoneになるという判定をしてそれ以上再帰しないようにする、のどちらかで、再帰を止めないといけません。

投稿2021/02/02 11:09

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問