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

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

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

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

Q&A

解決済

9回答

2004閲覧

JAVAに関してシンプルな書き方で変更したいです

benefit2025

総合スコア3

Java

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

0グッド

0クリップ

投稿2020/06/17 12:31

前提・実現したいこと

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ページで確認できます。

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

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

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

BluOxy

2020/06/17 12:33

どこの処理がシンプルに書けそうだと思いますか。
guest

回答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

raccy

総合スコア21739

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

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

swordone

2020/06/17 16:37

これ、順番保証ができないのでは…
raccy

2020/06/17 21:53

順番はバラバラでおかしくないはずなのですが、何故かソートされます。collectのドキュメントを読んでもよくわかりません。順番保証するなら、sorted()をかましたほうが良いかもしれませんね。 あとは、非常に低確率ですが、一回も出なかった目が表示されないというのもあります。これはどうすれば良いのか…こうなると、boxed()せずにIntStreamのままやったほうが良かったのかも知れません。
TN8001

2020/06/18 00:18

ばかばかしいですがこれはどうですか^^; IntStream.concat(IntStream.range(1, 6 + 1), new Random().ints(200, 1, 6 + 1)).boxed().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().map(e -> e.getKey() + " : " + "*".repeat(e.getValue().intValue() - 1)).forEach(System.out::println);
guest

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
kazuma-s

総合スコア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
iwamoto_takaaki

総合スコア2883

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

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

momon-ga

2020/06/23 11:05

ロジックとは関係ないですが > 実際の用例(特にイギリス英語)では「1個のさいころ」をa diceと呼ぶことは珍しくない。しかし正式には「diceはdieの複数形。単数形としてdiceを使うのは間違い」とされる。アメリカ英語ではdieとdiceを使い分ける傾向が強い。 元の質問者さんのこだわりを感じたので < DieA.roll あと、サイコロの目はeyeを使わないかなぁ。調べるとpipsやspotsというのが一般的のような気がします。
iwamoto_takaaki

2020/06/23 11:21

英語は弱いのでコメントいただけるのはありがたい。 DieA.rollってそういう意味だったんですね。 有難うございます。
guest

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

anndonut

総合スコア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

A-pZ

総合スコア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

momon-ga

総合スコア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

swordone

総合スコア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
htsign

総合スコア870

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

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

退会済みユーザー

退会済みユーザー

2020/06/17 12:52

元ソースは出た回数を記号の繰り返しで出力にみえるが
htsign

2020/06/17 12:56

質問者様とは出力が異なりますが、お題には反していないつもりでした。 一応回数を出力するものも付記しました。
htsign

2020/06/17 12:58

根本的に勘違いしていました。修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問