前提・実現したいこと
JAVAのソースを僕は下記のように書きましたが、
さらにシンプルな書き方があれば教えてください!!!
発生している問題・エラーメッセージ
下記の問題に関してです。 「サイコロを200回振りました.それぞれの出た目(1~6)の回数を記録し,「*」で表示しする」
該当のソースコード
JAVA
1import java.util.Scanner; 2import java.util.Random; 3 4public class Test { 5 public static void main(String[] args) { 6 7 int[] counts = new int[7]; 8 9 for (int i = 0; i <=200; i++) { 10 int a = DieA.roll(); 11 12 counts[a]++; 13 } 14 15 for (int i = 1; i < counts.length; i++) { 16 System.out.printf("%d : ", i); 17 for (int j = 0; j < counts[i]; j++) { 18 System.out.print("*"); 19 } 20 System.out.println(); 21 } 22 } 23} 24class DieA { 25 public static int roll() { 26 double r = Math.random() * 6; 27 int randInt = (int) r; 28 return randInt + 1; 29 } 30}
試したこと
シンプルな書き方で変更したい
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答9件
0
もうひと工夫欲しいところだけど、思いつかない。
参考: StreamでGroup By処理を行いたい(group-by-count, group-by-sum, group-by-max) - Qiita
Java
1import java.util.Random; 2import java.util.stream.Collectors; 3import java.util.function.Function; 4 5public class Test { 6 public static void main(String[] args) { 7 new Random() 8 .ints(200, 1, 7) 9 .boxed() 10 .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) 11 .entrySet() 12 .stream() 13 .map(e -> e.getKey() + " : " + "*".repeat(e.getValue().intValue())) 14 .forEach(System.out::println); 15 } 16}
投稿2020/06/17 15:44
総合スコア21739
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/17 16:37
2020/06/17 21:53
2020/06/18 00:18
2020/06/18 11:45
0
ベストアンサー
for (int i = 0; i <=200; i++)
これだと1回多くループしてしまいます。
また、わざわざDieAクラスを作る必要もないかと。
Java
1public class Test { 2 public static void main(String[] args) { 3 4 int[] counts = new int[7]; 5 6 for (int i = 1; i <= 200; i++) { //i = 0をi = 1に変更 7 int a = (int) (Math.random() * 6 + 1); //DieAクラスを削除 8 9 counts[a]++; 10 } 11 12 for (int i = 1; i < counts.length; i++) { 13 System.out.printf("%d : ", i); 14 for (int j = 0; j < counts[i]; j++) { 15 System.out.print("*"); 16 } 17 System.out.println(); 18 } 19 } 20}
投稿2020/06/17 13:23
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
さらにシンプルな書き方があれば教えてください!!!
Java
1public class Test { 2 public static void main(String[] s) { 3 int[] k = new int[6]; 4 for (int i = 0; i < 200; i++) 5 k[(int)(Math.random() * 6)]++; 6 for (int i = 0; i < 6; i++) 7 System.out.println(i+1 + ": " + "*".repeat(k[i])); 8 } 9}
追記
あなたの Java のバージョンは何ですか?
Java 11 以降でないと Stringクラスの repeatメソッドが使えないので、
次のようにしてみました。
Java
1class Test { 2 public static void main(String[] args) { 3 String s = new String(new char[200]).replaceAll(".", "*"); 4 int[] k = new int[6]; 5 for (int i = 0; i < s.length(); i++) 6 k[(int)(Math.random() * 6)]++; 7 for (int i = 0; i < 6; i++) 8 System.out.println(i+1 + ": " + s.substring(0, k[i])); 9 } 10}
追記2
substring の代わりに printf を使ってもできます。
diff
1- System.out.println(i+1 + ": " + s.substring(0, k[i])); 2+ System.out.printf("%d: %."+k[i]+"s\n", i+1, s);
投稿2020/06/23 12:11
編集2020/06/23 23:39総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
なんかガチな書き方が多いので、学生さま向けのライトな書き方をしてみたくなりました。
とはいえ、Javaは真面目に書いたこと無いので、"ちょっと違う"という点があれば優しく指摘下さい。
まず、解説をコメントしてたら長くなったのでコメント抜きで・・・
java
1public class Main { 2 static final int MAX_EYES = 6; 3 4 public static void main(String[] args) { 5 var counts = new int[MAX_EYES]; 6 7 for (var i = 0; i < 200; i++) { 8 var eyes = rollTheDice(); 9 counts[eyes]++; 10 } 11 12 for (var i = 0; i < MAX_EYES; i++) { 13 var count = counts[i]; 14 var bar = repeat('*', count); 15 var str = String.format("%d: %s", i + 1, bar); 16 System.out.println(str); 17 } 18 } 19 20 public static int rollTheDice(){ 21 return (int) (Math.random() * MAX_EYES); 22 } 23 24 public static String repeat(char c, int count) { 25 var sb = new StringBuilder(); 26 for(var i = 0; i < count; i++) { 27 sb.append(c); 28 } 29 return sb.toString(); 30 } 31}
コメント入りです。
java
1public class Main { 2 // サイコロの目の数は6面とは限らない 3 // 定数として外だしする 4 static final int MAX_EYES = 6; 5 6 public static void main(String[] args) { 7 // 自明な型はvarで問題ない 8 // 添字が0から始まるのは違和感があるが余分に取るとメモリを 9 // 消費するので慣れた人にはそちらのほうが気持ちが悪い 10 var counts = new int[MAX_EYES]; 11 12 // 200回回す場合のループはこのように書く場合が多い 13 // 0から始まった方が添え字に使いやすい 14 for (var i = 0; i < 200; i++) { 15 // サイコロを振るってことを関数名で説明する 16 // 賽の目ってeyesって言うこと知らなかった 17 var eyes = rollTheDice(); 18 counts[eyes]++; 19 } 20 21 // ループの回数が配列から取れる場合はいわゆるforeachを使う 22 // 記述がスッキリするだけでなく変数の長さの変更についていける 23 // ループの書き方は、かなりのパターンがあるので使い分けること 24 for (var i = 0; i < MAX_EYES; i++) { 25 // 一般的に、1行で書けることも分けた方が読みやすくなる 26 var count = counts[i]; 27 // 文字を繰り返すの部分は関数化するとスッキリする 28 var bar = repeat('*', count); 29 var str = String.format("%d: %s", i + 1, bar); 30 System.out.println(str); 31 } 32 } 33 34 // 1行でも関数化することによって読みやすくなるコードはある 35 public static int rollTheDice(){ 36 // さっき行を分けたのと逆に1行にするパターン 37 // 戻り値が変数のみになっていないのはなれると多い書き方 38 // 良い書き方かどうかは判らないがなれると良い 39 return (int) (Math.random() * MAX_EYES); 40 } 41 42 // 指定された文字を繰り返す関数 <- コメントもソースのうち 43 // 一文字ずつ出力するのも悪くないけど、まとめた形にしてくれる関数は便利 44 public static String repeat(char c, int count) { 45 // ループなどで不特定の回数の文字列の連結はStringBuilder推奨 46 // メモリを余分に使用しない 47 // あと、変数名は特にない場合は頭文字をとってsbとする 48 var sb = new StringBuilder(); 49 for(var i = 0; i < count; i++) { 50 sb.append(c); 51 } 52 return sb.toString(); 53 } 54}
投稿2020/06/23 10:28
編集2020/06/23 10:34総合スコア2883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/23 11:05
2020/06/23 11:21
0
私もpaiza.ioでへろへろと。
Java
1import java.util.*; 2 3public class Main { 4 public static void main(String[] args) throws Exception { 5 // Your code here! 6 Random r = new Random(); 7 int res[] = new int[6]; 8 for (int i = 0; i < 200; ++i) { 9 res[r.nextInt(6)]++; 10 } 11 12 for (int i = 0; i < 6; ++i) { 13 System.out.print(String.valueOf(i+1) + ": "); 14 for (int j = 0; j < res[i]; ++j) { 15 System.out.print("*"); 16 } 17 System.out.println(); 18 } 19 } 20}
投稿2020/06/17 13:58
総合スコア667
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
※Java11で記述しています
java
1import java.security.SecureRandom; 2import java.util.List; 3import java.util.stream.Collectors; 4import java.util.stream.IntStream; 5 6/** 7 * @author a-pz 8 * 9 */ 10public class DiceSample { 11 12 public static void main(String[] args) { 13 DiceSample sample = new DiceSample(); 14 sample.start(10); 15 16 } 17 18 public void start(int sampleCount) { 19 List<Integer> dices = dice(sampleCount); 20 IntStream.rangeClosed(1, 6).boxed().forEach(target -> { 21 int hit = (int)dices.stream().filter(val -> val == target).count(); 22 System.out.println(target + " " + "*".repeat(hit)); 23 }); 24 25 } 26 27 List<Integer> dice(int sampleCount) { 28 SecureRandom r = new SecureRandom(); 29 return r.ints(sampleCount, 1, 7).boxed().collect(Collectors.toList()); 30 } 31 32}
投稿2020/06/17 13:43
総合スコア12011
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
十分シンプルだと思いますが。
既出ですが、repeatのところだけ変更すれば十分だと思います。
あとは余計な一時変数を削除するだけでスッキリします。
※200回のループの条件が違うので修正
public class Test { public static void main(String[] args) { int[] counts = new int[7]; for (int i = 0; i < 200; i++) { // 200回なら =< でなく < counts[DieA.roll()]++; } for (int i = 1; i < counts.length; i++) { System.out.printf("%d : %s%n", i, "*".repeat(counts[i])); } } } class DieA { public static int roll() { return (int)(Math.random() * 6) + 1; } }
投稿2020/06/17 13:37
総合スコア4826
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
「さいころを振る」メソッドとしてDieA.rollメソッドがあるようですが、1箇所でしか使っておらず、それほど行数もないので、メソッド化する意味はあまりなさそうです。そしてこの程度の処理ならば1文で書けます。
また、さいころの目が16であるため、配列の16を使うために7要素で宣言しているようですが、「さいころの目-1」としてみなせば0~5の6要素で事足ります。
また、現在のコードでは200回ではなく、201回の繰り返しになります。
以上まででコードを書くと次のようになります。
java
1import java.util.Scanner; 2import java.util.Random; 3 4public class Test { 5 public static void main(String[] args) { 6 7 int[] counts = new int[6]; 8 9 for (int i = 0; i < 200; i++) { 10 int a = (int)(Math.random() * 6); 11 counts[a]++; 12 } 13 14 for (int i = 0; i < counts.length; i++) { 15 System.out.printf("%d : ", i + 1); 16 for (int j = 0; j < counts[i]; j++) { 17 System.out.print("*"); 18 } 19 System.out.println(); 20 } 21 } 22}
シンプルの意味合いにもよりますが、これ以上シンプルに書くのは困難だと思われます。
投稿2020/06/17 13:34
総合スコア20669
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Java 11 で書きました。
問題文を理解しておらず、的外れなコードを書いていたため修正しています。失礼しました。
java
1import java.util.Map; 2import java.util.Random; 3import java.util.stream.Collectors; 4import java.util.stream.Stream; 5 6public class Test { 7 public static void main(String[] args) { 8 var rnd = new Random(); 9 Map<Integer, Long> counts = Stream.generate(() -> rnd.nextInt(6) + 1) 10 .limit(200) 11 .collect(Collectors.groupingBy(n -> n, Collectors.counting())); 12 13 for (var entry : counts.entrySet()) { 14 int n = entry.getKey(); 15 int count = entry.getValue().intValue(); 16 System.out.printf("%d : %s\n", n, "*".repeat(count)); 17 } 18 } 19}
一応ほとんどの場合は上記のコードで期待通りになると思います。
無視できるほどの低確率だとは思いますが(200回中一度も1が出ないなどの)偏りが出た場合、抜ける可能性がありますね…。
投稿2020/06/17 12:46
編集2020/06/17 13:25総合スコア870
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。