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

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

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

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

Q&A

解決済

2回答

5234閲覧

重複しない乱数の生成

mayon

総合スコア8

Java

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

0グッド

0クリップ

投稿2017/12/25 06:26

編集2017/12/25 08:57

重複しない5桁の乱数の生成で、とあるコーディングを見つけたのですが、
どのような仕組みになっているのかの詳細が知りたいです。
長いため、乱数のメソッドのみ表示します。

public static String randomNum() { int[] numArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (int i = 0; i < 6; i++) { int a = (int) (Math.random() * 10); int b = (int) (Math.random() * 10); int temp = numArray[a]; numArray[a] = numArray[b]; numArray[b] = temp; } StringBuffer stringBuffer = new StringBuffer(5); for (int i = 0; i < 5; i++) { stringBuffer.append(String.valueOf(numArray[i])); } return stringBuffer.toString();

numArrayという配列を作成し、aとbでランダムな数字を2つ作成してその後どのようにして5桁の数字を導き出しているのかよくわかりませんでした。。
なぜnumArray[a] = numArray[b];という風に配列を入れ替える必要があるのでしょうか?

for (int i = 0; i < 6; i++) { int a = (int) (Math.random() * 10); int b = (int) (Math.random() * 10);

なぜここは6回繰り返す必要があるのでしょうか?
メカニズムについてかみ砕いて教えていただけるととても助かります。

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

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

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

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

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

guest

回答2

0

「ランダムに2箇所選んで、それを交換する」ということを5回繰り返しています。

ただし、この方法では乱数の消費が多く、かつ厳密に均等にならないので、あまりおすすめはできません。「配列をランダムに並べ替える」のにはFisher-Yates法という定番の手法があるので、それを使いましょう。

10個全部並べ替えてしまう無駄があっても気にしないのなら、Java標準であるCollections.shuffleを使えば自前実装は不要です。

Javaでの実装例と説明

投稿2017/12/25 06:30

編集2017/12/25 06:34
maisumakun

総合スコア145184

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

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

mayon

2017/12/25 06:52

迅速な回答ありがとうございます。 確かに、実際使うとしたらshuffleの方が効率が良いですね! しかし、このコーディングも1つのパターンとして理解しておきたいと思っております。 「ランダムに2箇所選んで、それを交換する」の解釈についてですが、 めっきり初心者なため、もう少しかみ砕いてご教授いただければ幸いです。 int[] numArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (int i = 0; i < 6; i++) { int a = (int) (Math.random() * 10); //↑の配列からランダムに選ぶを6回繰り返し int b = (int) (Math.random() * 10); //↑の配列からランダムに選ぶ6回繰り返し int temp = numArray[a]; //aとbの交換作業 numArray[a] = numArray[b]; numArray[b] = temp; } StringBuffer stringBuffer = new StringBuffer(5); // 5桁に格納していく for (int i = 0; i < 5; i++) { stringBuffer.append(String.valueOf(numArray[i])); // ここでは何をしているのでしょうか? }
guest

0

ベストアンサー

メソッド内で二つの処理がなされているために混乱しているようです。
それぞれ分割して考えると良いでしょう。

シャッフルしている部分について

既にmaisumakunさんが回答されている通りです。
ピンと来ないのなら、可視化してみると良いでしょう。

Java

1public static String randomNum() { 2 int[] numArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 3 4 // なんとなく6回繰り返すよ。回数は適当だよ。 5 for (int i = 0; i < 6; i++) { 6 // 0~9の値をランダムに決めるよ。 7 int a = (int) (Math.random() * 10); 8 int b = (int) (Math.random() * 10); 9 10 // 入れ替えるよ。いわゆる『スワップ』だよ。  11 int temp = numArray[a]; 12 numArray[a] = numArray[b]; 13 numArray[b] = temp; 14 }

その後の処理について

戻り値をString型にするために、int[]からStringへの置換を試みています。
その際、StringBufferを噛ませることで、処理の効率化を図っています。

Java

1 // 長さ5のインスタンスを作るよ。 2 StringBuffer stringBuffer = new StringBuffer(5); 3 4 for (int i = 0; i < 5; i++) { 5 // 一個ずつ加えて(append)いくよ。 6 stringBuffer.append( 7 // numArray[i]をString型に変更するよ。 ex) 1 -> "1" 8 String.valueOf(numArray[i]) 9 ); 10 } 11 return stringBuffer.toString(); 12}

なお、次のように書いても動作は同じですが、処理効率が悪いので避けた方がよいです。
しかしこれならなんとなく意味がわかるのではないでしょうか?

Java

1 String ret = ""; 2 for(int i = 0; i < 5; i++) { 3 ret = ret + String.valueOf(numArray[i]); 4 } 5 return ret; 6}

投稿2017/12/25 09:09

編集2017/12/25 09:24
LouiS0616

総合スコア35660

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

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

mayon

2017/12/26 08:47

とても混乱していたようです。すごく分かりやすかったです。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問