teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

Streamを使ってみようとした

2016/05/07 17:32

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -26,7 +26,49 @@
26
26
  }
27
27
 
28
28
  ```
29
+ 更にこれをなんとかStreamで書けないか試してみた…が、余り綺麗に書けなかったです。
30
+ ```java
31
+ import java.util.ArrayList;
32
+ import java.util.Arrays;
33
+ import java.util.List;
34
+ import java.util.function.Function;
35
+ import java.util.stream.IntStream;
36
+ import java.util.stream.Stream;
29
37
 
38
+ public class Q34167_2 {
39
+ public static void main(String[] args) {
40
+ int[] coins = {1, 5, 10, 50, 100, 500};
41
+
42
+ // 一枚しか使えない硬貨
43
+ List<Integer> once = Arrays.asList(new Integer[]{5, 50, 500});
44
+
45
+ // Stream内のListの最後の番号に応じ、次の番号を詰めたすべてのパターンのListのStreamを返す
46
+ Function<List<Integer>, Stream<List<Integer>>> f =
47
+ e -> {
48
+ int last = e.get(e.size() - 1);
49
+ if (once.contains(coins[last])){
50
+ last++;
51
+ }
52
+ return IntStream.range(last, coins.length).mapToObj(i -> {
53
+ List<Integer> l = new ArrayList<>(e);
54
+ l.add(i);
55
+ return l;
56
+ });
57
+ };
58
+
59
+ IntStream.range(0, coins.length).mapToObj(i -> {
60
+ List<Integer> list = new ArrayList<>();
61
+ list.add(i);
62
+ return list;
63
+ }).flatMap(f).flatMap(f)
64
+ .mapToInt(e -> e.stream().mapToInt(i -> coins[i]).sum())
65
+ .sorted().forEach(System.out::println);
66
+ }
67
+
68
+ }
69
+
70
+ ```
71
+
30
72
  旧回答
31
73
  ---
32
74
  この手の問題では、**制約の厳しいものから考える**ことが鉄則です。今回の場合、「5円、50円、500円は最大1枚しか使えない」という制約があるので、これから考えます。

1

コード

2016/05/07 17:32

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -1,5 +1,33 @@
1
+ ちょっとした工夫を思いついてしまったので、そのコードを書いてしまいます(Java8)。
2
+ ```java
3
+ import java.util.ArrayList;
4
+ import java.util.Arrays;
1
- コード化はまだですが、考え方を…
5
+ import java.util.List;
2
6
 
7
+ public class Q34167_2 {
8
+ public static void main(String[] args) {
9
+ int[] coins = {1, 5, 10, 50, 100, 500};
10
+
11
+ // 一枚しか使えない硬貨
12
+ List<Integer> once = Arrays.asList(new Integer[]{5, 50, 500});
13
+ List<Integer> total = new ArrayList<>();
14
+ for (int i = 0; i < coins.length; i++) {
15
+
16
+ // 一枚しか使えない硬貨を前のステップで使っていた場合には次の硬貨から、そうでなければ同じ硬貨から選択
17
+ for(int j = once.contains(coins[i]) ? i + 1 : i; j < coins.length ; j++) {
18
+ for (int k = once.contains(coins[j]) ? j + 1 : j; k < coins.length; k++){
19
+ total.add(coins[i] + coins[j] + coins[k]);
20
+ }
21
+ }
22
+ }
23
+ total.stream().sorted().forEach(System.out::println);
24
+ }
25
+
26
+ }
27
+
28
+ ```
29
+
30
+ 旧回答
3
31
  ---
4
32
  この手の問題では、**制約の厳しいものから考える**ことが鉄則です。今回の場合、「5円、50円、500円は最大1枚しか使えない」という制約があるので、これから考えます。
5
33