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

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

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

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

Q&A

3回答

467閲覧

0.1~1.0未満の乱数を10000個生成しヒストグラムを作る問題が解けずに困っております。

LgjtY1j6PUkCqKA

総合スコア8

Java

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

0グッド

0クリップ

投稿2017/06/20 06:56

編集2022/01/12 10:55

10000個生成した乱数を
1:0.00.2
2:0.2
0.4
3:0.40.6
4:0.6
0.8
5:0.8~1.0
のレベルに分類して、
縦軸を1000、2000,3000とし、
横軸を分類した1、2、3、4、5、としたヒストグラムを作成したいのですが
生成した乱数をグラフになかなかできません。
また、乱数の生成のさせ方は下のソースコードのような形でよろしいのでしょうか。
教えて欲しいです。

import java.util.Random; public class S7015507_Kadai1_5{ //メインメソッド public static void main (String[] args){ //Randomクラスのインスタンスを生成 Random rnd = new Random(); double dbl_data; //カウンタを用意し、初期化 int [] count_dbl_data={0,0,0,0,0,0,0,0,0,0,}; //double型の乱数(0〜100未満)を10000個生成し、表示 System.out.println("double型の乱数を生成"); for (int i=0; i<10000; i++){ dbl_data =rnd.nextDouble(); //if文でカウンタに振り分け if(dbl_data<0.1){ count_dbl_data[0]++; } else if(dbl_data<0.2){ count_dbl_data[1]++; } else if(dbl_data<0.3){ count_dbl_data[2]++; } else if(dbl_data<0.4){ count_dbl_data[3]++; } else if(dbl_data<0.5){ count_dbl_data[4]++; } else if(dbl_data<0.6){ count_dbl_data[5]++; } else if(dbl_data<0.7){ count_dbl_data[6]++; } else if(dbl_data<0.8){ count_dbl_data[7]++; } else if(dbl_data<0.9){ count_dbl_data[8]++; } else{ count_dbl_data[9]++; } } //各レベルの表示 for(double i=0; i<10; i++){ System.out.println("0.0~0.1未満"+count_dbl_data[0]); System.out.println("0.1~0.2未満"+count_dbl_data[1]); System.out.println("0.2~0.3未満"+count_dbl_data[2]); System.out.println("0.3~0.4未満"+count_dbl_data[3]); System.out.println("0.4~0.5未満"+count_dbl_data[4]); System.out.println("0.5~0.6未満"+count_dbl_data[5]); System.out.println("0.6~0.7未満"+count_dbl_data[6]); System.out.println("0.7~0.8未満"+count_dbl_data[7]); System.out.println("0.8~0.9未満"+count_dbl_data[8]); System.out.println("0.9~1.0未満"+count_dbl_data[9]); } } }

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

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

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

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

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

fuzzball

2017/06/20 07:02

コードは ``` で囲って下さい。あと、タイトル間違ってます。
LgjtY1j6PUkCqKA

2017/06/20 07:07

初めての投稿でよくわからなくて、申し訳ございません。タイトルはどのようになおせばよろしいのでしょうか?
LgjtY1j6PUkCqKA

2017/06/20 07:24

やっとわかりました。嫌な思いさせてしまい、申し訳ございませんでした。
guest

回答3

0

乱数の生成のさせ方は下のソースコードのような形でよろしいのでしょうか。

致命的な間違いはないと思いますが、「あまりよくない」と思えることがあるのでコメントしてみます。

  • dbl_data

宣言をfor文の外側で行っています。しかしこの変数にアクセスしているのはfor文の内側のブロックの中だけです。こんなときはfor文の内側で宣言した方がよいと思います。「変数を宣言するとその度に何かの処理が動いて遅くなるような気がする」ことがあるかも知れませんが、Javaであればそういうことを気にする必要はありません。(大抵のコンパイラー言語でも同様だと思います)

  • count_dbl_data

初期値として{ 0, 0, ... }のような構文を使っていますね。要素数を注意深く数えると必要な要素分だけ定義できているかどうか確認はできますが、しかし値が全て0なので、こう書くよりは必要な要素数を用いてnew int[5]と書いた方が明快です。

  • if文の羅列

こういう「同じような処理を並べる」のは「書くときに間違い易く、また間違いがないかを確認するときにめんどくさい」ため多くのプログラマーはいやがると思います。プログラミングに慣れてくると「いかに単純にかけるか」をだんだんとうまく書けるようになってきます。ここでやりたいことは「ある値が等間隔で区切られた区間のどこに属するか」なのですが、次のような工夫ができます。つまり30行程度のif文の羅列が2行で済むことに・・・

java

1int index = (int)(dbl_data * 5); 2count_dbl_data[index]++;

このようなコードを間違いなく書くにはある程度の知識も併せて必要です。乱数は絶対に1未満の値でありそれを5倍して整数化しても「決して5以上の値にはならない」ことが確信をもってわかっていなければなりません。

  • count_dbl_data再び

上の指摘でnew int[5]の方がよいと書きました。しかし5はmagic numberと呼ばれる「プログラムに出現する意味がよくわからない定数」として嫌われることがあります。プログラムの論理は任意の数を5個の区分に分類して集計するので5に名前をつけたほうがより明快になります。

java

1static final int NUM_OF_CLASSIFICATIONS = 5; 2 3... 4int[] count_dbl_data = new[NUM_OF_CLASSIFICATIONS]; 5for (...省略...) { 6 ...省略... 7 int index = (int)(dbl_data * NUM_OF_CLASSIFICATIONS); 8 count_dbl_data[index]++; 9}
  • 変数名

自分も人のことを言えるほどはうまくできないのですが・・・昔ある人に「変数やクラスの名前の最後にdataとかinformation」と付けるのはナンセンスと言われたことがあります。「プログラムで扱うのはなんでもそうだけど、何かのデータや情報なんだからdata, informationとわざわざ付けるのは筋がわるい」というのがその人の主張でした。自分はその主張をもっともに感じたのでdataなどの単語が使いたくなった時に「ちょっと待て!」と考えるようになりました。
本プログラムの例でいえばdbl_dataでなくて単にvalueでよいし、count_dbl_dataは単にcountersでよいかも知れません。(英語センスがない自分はこうした名前を考えるとき結構まよったりします。が、ちょっと考えてよりましな名前を付けられるならそれは無駄ではないと思っています)


縦軸を1000、2000,3000とし、

横軸を分類した1、2、3、4、5、としたヒストグラムを作成したいのですが
生成した乱数をグラフになかなかできません。

本当の質問意図はこちらの方だと思いますが、上のコメントのうち「if文を減らすためにある値を別の値へ変換する」ことや「繰り返し文の中でどのように共通の書き方をするか」が考えらるようになってくるとヒストグラムを作るという論理が考えられると思います。
1000, 2000, 3000に到達しているかどうかを以下のようなループでしか書けないとしたらプログラムを書くのは大変苦痛になることでしょう。

java

1for (int i = 0; i < count_dbl_data.length; i++) { 2 if (count[i] > 3000) { 3 System.out.print(" * "); 4 } else { 5 System.out.print(" "); 6 } 7} 8System.out.println(); 9for (int i = 0; i < count_dbl_data.length; i++) { 10 if (count[i] > 2000) { 11 System.out.print(" * "); 12 } else { 13 System.out.print(" "); 14 } 15} 16System.out.println(); 17...

具体的なヒントでなくてゴメンナサイ。

投稿2017/06/20 07:59

編集2017/06/20 08:36
KSwordOfHaste

総合スコア18392

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

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

momon-ga

2017/06/20 08:22 編集

好みだと思いますが、私はこっちで書きます。 int index = (int)(dbl_data / 0.2); count_dbl_data[index]++; というか大元のソースコードにだまされましたが、区間の幅は0.2単位ですね。
KSwordOfHaste

2017/06/20 08:37 編集

> 0.2単位 ありゃりゃ・・・ご指摘ありがとうございます。回答を訂正しておきました。 > dbl_data / 0.2 これも分かり易さとしてはよいと思います。ただ、区間が3だったりすると気持ち悪いというのが自分の感覚です。dbl_data / (1/3.0)とすると分母の誤差のためにまかり間違って3になってしまうことがないか気にしなくてはならないような気が・・・
guest

0

他の方がソースについてはいろいろ詳しくかかれているので。
「乱数の生成のさせ方は下のソースコードのような形でよろしいのでしょうか。」
というところだけ補足。
Javaの乱数生成はどのパッケージの"Random"を選ぶかが実は重要。
java.util.Randomはぶっちゃけ偏ります("Java 乱数 偏り"で検索検索)。
他の選択肢としては
1.java.security.SecureRandom
2.java.lang.Math#random()
3.メルセンヌツイスタ使う
セキュリティなら1必須、製品に使うなら3、とりあえず生のjava.util.Randomより品質を求めるなら2とか(あと並行処理で性能でるやつとかあるそうですが、使ったことは無い)。

投稿2017/06/22 05:40

kurokoba

総合スコア276

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

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

0

JavaのRandom::nextDouble()は0.1~1.0の範囲の乱数になりますが、小数第1位の以下の値も入ってきます。(例えば0.2345・・・もあるということ)
なので、整数で0~9までの乱数を取得して+1した上で10で割って0.1~1.0の乱数を作ればいいと思います。

java

1bl_data = (double)(rnd.nextInt(10) + 1) / 10.0;

投稿2017/06/20 08:35

PineMatsu

総合スコア3579

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問