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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Python

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

Q&A

解決済

2回答

2974閲覧

部分和問題のif文の中身が何をしているのかわからない

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

0クリップ

投稿2017/07/15 02:58

部分和問題のif文の中身が何をしているのかわからないです。
http://y0m0r.hateblo.jp/entry/20121203/1354549288
を参考に部分和問題を書いたら

# coding=utf-8 # 部分和問題 # 深さ優先検索 # 整数がn個与えられる。その中からいくつか選び、その環をちょうどkにすることができるかどうかを判定する def solve(integer_list, target_sum, i=0, sum=0): if i == len(integer_list): return sum == target_sum if (solve(integer_list, target_sum, i + 1, sum)): return True if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])): return True return False # n個の整数 integer_list = [1,3,5,12,7] # k target_sum = 11 print(solve(integer_list, target_sum)) # => True

のようになったのですが、
この

if (solve(integer_list, target_sum, i + 1, sum)): return True if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])): return True

の中のif文の条件が何をしているのかわかりません。

if (solve(integer_list, target_sum, i + 1, sum)):
if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])):

は何の機能なのでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

再帰処理ですね。
solveの引数は、次のように解釈するといいかと思います。

  • integer_list

文字通り、整数のリスト。途中変更されることはない。([1,3,5,12,7])

  • target_sum

文字通り、対象となる和。途中変更されることはない。(11)

  • i

どこまでリストを見たか記憶している変数。

  • sum

これまでの和。

さらに、それぞれのif文は、次を意味します。

  • if i = len(integer_list): 終了条件

リストの全てをチェックした場合、現段階の合計がtarget_sumと等しければTrueを返す。
異なる場合はFalseを返す。

  • if (solve(integer_list, target_sum, i + 1, sum)):

今着目している数値(integer_list[i])を足さずに、次の数値に着目する。

  • if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])):

今着目している数値(integer_list[i])を足して、次の数値に着目する。


これらを把握したうえで、プログラムの処理を追ってみましょう。
solve([1,3,5,12,7], 11, 0, 0)が呼ばれると、次の二パターンに分割して問題を解決します。
0. 0番目の数値をsumに足す場合
次のようにsolveを呼び出し、判断を次のsolveに委託します。solve([1,3,5,12,7], 11, 1, 1)
0. 0番目の数値をsumに足さない場合
次のようにsolveを呼び出し、判断を次のsolveに委託します。solve([1,3,5,12,7], 11, 1, 0)

... どんどん二分割されていきます ...

これをある程度続けていくと、いつかリストの最後まで見ることになります。
その時の条件が、i == len(integer_list)です。
例えばsolve([1,3,5,12,7], 11, 5, 11)が呼ばれると、終了条件に達します。

リスト長がこの場合5ですから、2の5乗で32パターンに分割されますが、
それぞれが必ず終了条件に達し、結論がTrue/Falseで返されます。


私も初めて再帰処理を見たとき、狐に化かされたような気がしました。
面倒でも、ひとつひとつ紙に書いてみると、感覚がつかめるかもしれません。

投稿2017/07/15 03:26

LouiS0616

総合スコア35660

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

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

退会済みユーザー

退会済みユーザー

2017/07/15 12:01

ありがとうございます。 if (solve(integer_list, target_sum, i + 1, sum)): return True if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])): return True で2つのif文の sum の値の保存はどこで行われているのでしょうか? i + 1でiがどんどん増えていく理由はわかるのですが。
退会済みユーザー

退会済みユーザー

2017/07/15 12:04

また、2つのif文のreturn True で一度2つのif文が呼ばれればsolveメソッドはTrueを返すと思ったのですが、それは違うのでしょうか?(なら必ずこのメソッドはTrueを返すような気がしたのですが...)
LouiS0616

2017/07/15 12:17

sumの値は保存されません。毎度毎度引数として渡されます。 実際に紙に書いてみると、sumの値を変数に保存しなくても済む感覚が掴めるかと思います。
LouiS0616

2017/07/15 12:21 編集

> 2つのif文のreturn trueで... ちょっと待ってください。Trueが返されるのは、if文の条件が真のときのみです。 そういう意味で、『判断を次のsolveに委託します』という表現を使いました。 全てのif文の条件がFalseとなったとき、solve関数最終行に到達し、solveはFalseを返します。
guest

0

単純に自身を呼び出しているだけです。
最終的にiとinteger_listの長さが同じになるのでbool値がreturnされます。結果として条件文の判定として使われています。

再帰関数について調べてみると良いです。

投稿2017/07/15 03:11

_Victorique__

総合スコア1392

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問