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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

再帰

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

Q&A

3回答

2672閲覧

Java再帰について

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

再帰

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

0グッド

0クリップ

投稿2015/06/20 08:48

編集2015/06/20 09:25

以下のコードがどのような挙動をするかがわかりません。
漠然とした質問の仕方で恐縮ですが、回答頂けますと幸いです。

lang

1/** 2 * 数値のリストから数式の全組み合わせを作成して、文字列のストリームで返す。 3 * 例:[1, 2] -> ["1 +2", "1 -2", "12"] 4 */ 5 static Stream<String> f(List<Integer> vals) { 6 if (vals.size() == 1) { 7 return Stream.of(vals.get(0).toString()); 8 } 9 return Stream.of(" +", " -", "") 10 .flatMap(op -> f(vals.subList(1, vals.size())) 11 .map(x -> vals.get(0).toString() + op + x) 12 ); 13 }

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

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

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

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

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

guest

回答3

0

lang

1static Stream<String> f(List<Integer> vals) { 2 if (vals.size() == 1) { 3 return Stream.of(vals.get(0).toString()); 4 } 5 return Stream.of(" +", " -", "") 6 .flatMap(op -> f(vals.subList(1, vals.size())) 7 .map(x -> vals.get(0).toString() + op + x) 8 ); 9 } 10// f([2,3]) 再帰でもとの処理に戻る 11// f([3]) 再帰でもと処理にもどる 12// if (vals.size() == 1) の処理にはいり、3.toString()の処理をおこなう 13// return Stream.of(" +", " -", "").flatMap(op -> f(vals.subList(1, vals.size())) 14// f([3]) 再帰でもと処理にもどる 15// この永遠のループで 16// map(x -> vals.get(0).toString() + op + x) 17// の処理に入れないような気がするのですが、どのタイミングでどうして 18// map(x -> vals.get(0).toString() + op + x)の処理にはいれるのでしょうか 19

投稿2015/06/21 03:13

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

swordone

2015/06/21 03:43

永遠のループではないですよ. f([2,3])の処理の中でf(vals.subList(1, vals.size())は"3"という文字列だけを持ったStream(streamAとします)を返します.(f([2,3]の中のf([3])が解決する)すると f([2,3])の中のstreamA.map(x -> vals.get(0).toString() + op + x)の処理に入ります. opはStream.of(" +", " -", "")で生成されるStreamから順番に,つまりこの括弧内の要素が順番に取り出されます. "Stream("3")"の書き方が悪かったようです.申し訳ない.
argius

2015/06/21 03:45

f([3])のときは、return Stream.of(vals.get(0).toString());でメソッドを抜けて return Stream.of(" +"...は評価されないので、永遠のループにはなりませんね。
退会済みユーザー

退会済みユーザー

2015/06/21 04:13

swordoneさん、argiusさん ご回答ありがとうございます。 理解できた気がします。 ベストアンサーに処理の順を書いてみたのですが、理解があっているか、 お時間あります際に確認いただけますと幸いです。
guest

0

概念的に説明しようとするとこうなるかと思います.
f([1,2,3])
→f([2,3]) :先頭の要素を抜いた配列を新たに渡す
→f([3])→Stream("3") :1つだけになったらStream化
→Stream(" +", " -", "").flatMap(op ->Stream("3").map(x -> "2" + op + x)
→"2",op(∈{" +", " -", ""}),x(∈{"3"})の順に要素を取って樹形図を書くように文字列決定
→Stream("2 +3", "2 -3", "23")
→Stream(" +", " -", "").flatMap(op ->Stream("2 +3", "2 -3", "23").map(x -> "1" + op + x)
→"1",op(∈{" +", " -", ""}),x(∈{"2 +3", "2 -3", "23"})
→"1 +2 +3", "1 +2 -3", "1 +23"; "1 -2 +3", "1 -2 -3", "1 -23";"12 +3", "12 -3", "123"

投稿2015/06/20 10:15

swordone

総合スコア20651

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

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

退会済みユーザー

退会済みユーザー

2015/06/21 03:18

swordoneさん 回答いただきまして、ありがとうございます。 理解できないポイントをベストアンサーに記載いたしました。 (ここだとコードでかけないようでみにくいのでベストアンサーに記しました。) 時間のある際にお答えいただけますと、幸いです。
guest

0

分かりやすくするために、コードを一部変形しています。

f[1, 2]が渡されたときの値と処理イメージだけコード内のコメントに記載しています。

lang

1static Stream<String> f(List<Integer> vals) { 2 // vals = [1, 2] 3 if (vals.size() == 1) { 4 return Stream.of(vals.get(0).toString()); 5 // 今回の内容とは直接関係ありませんが 6 // ここは return vals.stream().map(Object::toString); 7 // のほうが良いと思います。 8 } 9 String head = vals.get(0).toString(); 10 // head = 1 11 List<Integer> tail = vals.subList(1, vals.size()); 12 // tail = [2] 13 return Stream.of(" +", " -", "").flatMap(op -> f(tail).map(x -> head + op + x)); 14 // [ " +", " -", "" ] をひとつずつopとして以下の処理を行う 15 // => tailに対して、ひとつずつxとして以下の処理を行う 16 // => tailはこの場合[2]だけなので、文字列 1 + op + 2 を生成 17 // つまり 18 // " +" => "1 +2" 19 // " -" => "1 -2" 20 // "" => "12" 21 // を生成して、それをストリームで返す 22}

考え方としては以上のようになります。
ただし、実際にストリームの処理が実行されるのは、collectforEachのような終端処理を呼び出してからになります。そのため、一部変形した部分の処理順序は変わってしまいますが、意味と結果は同じになるはずです。

投稿2015/06/20 09:44

編集2015/06/21 03:42
argius

総合スコア9390

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

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

退会済みユーザー

退会済みユーザー

2015/06/20 10:00

argiusさん 回答いただきましてありがとうございます。 String head = vals.get(0).toString(); 上記の時点ではvals=[1,2]であり、 if (vals.size() == 1) { return Stream.of(vals.get(0).toString()); } は適応されないようにおもうのですが、いかがでしょうか? また、vals= [1,2,3]の場合で同じようになるのでしょうか?
argius

2015/06/20 10:06

すみません、書き方が分かりづらかったですね。 おっしゃるとおり、vals=[1,2]のときはif (vals.size() == 1) { ... } は評価されません。 vals= [1,2,3]の場合はこれより少しだけ複雑になりますので、まずは一旦、この方式でご理解いただいたほうが良いと考えました。
退会済みユーザー

退会済みユーザー

2015/06/21 03:14

```lang-java static Stream<String> f(List<Integer> vals) { if (vals.size() == 1) { return Stream.of(vals.get(0).toString()); } return Stream.of(" +", " -", "") .flatMap(op -> f(vals.subList(1, vals.size())) .map(x -> vals.get(0).toString() + op + x) ); } // f([2,3]) 再帰でもとの処理に戻る // f([3]) 再帰でもと処理にもどる // if (vals.size() == 1) の処理にはいり、3.toString()の処理をおこなう // return Stream.of(" +", " -", "").flatMap(op -> f(vals.subList(1, vals.size())) // f([3]) 再帰でもと処理にもどる // この永遠のループで // map(x -> vals.get(0).toString() + op + x) // の処理に入れないような気がするのですが、どのタイミングでどうして // map(x -> vals.get(0).toString() + op + x)の処理にはいれるのでしょうか ```
退会済みユーザー

退会済みユーザー

2015/06/21 03:16

argiusさん なんどもお答えいただきましてありがとうございます。 理解できないポイントをベストアンサーに記載いたしました。 (ここだとコードでかけないようでみにくいのでベストアンサーに記しました。) 時間のある際にお答えいただけますと、幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問