以下のコードがどのような挙動をするかがわかりません。
漠然とした質問の仕方で恐縮ですが、回答頂けますと幸いです。
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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
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
総合スコア20651
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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}
考え方としては以上のようになります。
ただし、実際にストリームの処理が実行されるのは、collect
やforEach
のような終端処理を呼び出してからになります。そのため、一部変形した部分の処理順序は変わってしまいますが、意味と結果は同じになるはずです。
投稿2015/06/20 09:44
編集2015/06/21 03:42総合スコア9390
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/06/20 10:00
2015/06/20 10:06
退会済みユーザー
2015/06/21 03:14
退会済みユーザー
2015/06/21 03:16
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/06/21 03:43
2015/06/21 03:45
退会済みユーザー
2015/06/21 04:13