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

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

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

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

Q&A

解決済

2回答

1663閲覧

java 解釈

code_red_sky928

総合スコア9

Java

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

0グッド

0クリップ

投稿2015/01/09 20:27

javaでコードを見てもどうしてこんなコードになっているかわからないものがあるので解釈を教えて下さい。

int[] answer = new int[3];//答えが入る
//ランダムな答えを作成
//ただし同じ数字が無いようにする
for (int i = 0; i < answer.length; i++) {
//自分より前の要素にかぶる奴がないか確かめる
//あったらもう1回random
boolean flag = false;
answer[i] = (int) (Math.random() * 6 + 1);
do {
flag = false;
for (int j = i - 1; j >= 0; j--) {
if (answer[i] == answer[j]) {
flag = true;
answer[i] = (int) (Math.random() * 6 + 1);
}
}

} while (flag == true);

これでどのようにしてかぶっている要素を見つけられるのでしょうか??

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

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

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

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

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

guest

回答2

0

do文内の以下のif文で、かぶっているかを判定しているようです。

if (answer[i] == answer[j]) {

このときflagtrueを代入し、再度乱数を取得しています。
do文はflagが'false'のときに抜けるようになっているので、doを抜けると要素はかぶっていない状態です。

ご期待の回答でしょうか。

Setを使って、要素数が3になるまで、乱数をセットする方法はいかがでしょうか。

lang

1Set<Integer> answerSet = new HashSet<Integer>(); 2do { 3 answerSet.put((int) (Math.random() * 6 + 1)); 4} while (answerSet.size() < 3); 5int[] answer = ArrayUtils.toPrimitive(answerSet.toArray(new Integer[0]));

すみません、この方法ですと、Integerのハッシュなので、取得した配列は値の昇順になってしまいます。
HashSetではなく、LinkedHashSetを使うことで解決すると思います。

投稿2015/01/10 00:41

jcs502ulf

総合スコア307

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

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

code_red_sky928

2015/01/10 03:10

迅速な回答有難うございました!!理解出来ました
guest

0

ベストアンサー

まず、answerの初期状態は、[0, 0, 0]です。
ランダム値はサイコロと同じ1~6のどれかになります。

外側のforループは、for (int i = 0; i < answer.length; i++)
なので、最初はanswer[0]にランダム値を入れます。
5が入ったとすると、answer[5, 0, 0]になります。
内側のループはfor (int j = i - 1; j >= 0; j--)ですが、
i = 0の時は最初の時点でj >= 0を満たさないので、
forループに入らずに進み、flag=falseのままなのでdo whileも抜けて
次に進みます。

次は、i = 1になるのでanswer[1]にランダム値を入れます。
4が入ったとすると、answer[5, 4, 0]になります。
内側のforループは、i = 1の時はfor (int j = 1 - 1; j >= 0; j--)
になりますので、1回だけ、つまり
自分より前の要素answer[0]とだけ同じかどうか確かめます。
この場合は54ですから、同じでないので、flag=falseのままになり、
do whileを抜けて次に進みます。

★目印

次は、i = 2になるのでanswer[2]にランダム値を入れます。
5が入ったとすると、answer[5, 4, 5]になります。
内側のforループは、i = 2の時はfor (int j = 2 - 1; j >= 0; j--)
になりますので、自分と自分より前の要素answer[1]answer[0]と順に確かめます。
この場合は、answer[2] == answer[1]は等しくありませんが、
answer[2] == answer[0]は等しいので、if文の中に入ります。
if文の中では、flag=trueにして、answer[2]にランダム値を入れます。
2が入ったとすると、answer[5, 4, 2]になります。
flag=trueになったので、doの次(「★目印」)に戻ってからもう一度同じことをします。

i = 3になると、外側のfor文の条件を満たさなくなりますので、ループが終了し
すべての計算が終了します。

長くなりましたが、このようにして、値がかぶらないようにしています。

ただ、正直あまり良いコードでは無いですね。
randomするところが2箇所にあったりループが複雑すぎる気がします。
例:

lang

1loop1: 2for (int i = 0; i < answer.length;) { 3 answer[i] = (int)(Math.random() * 6 + 1); 4 for (int j = i - 1; j >= 0; j--) { 5 if (answer[i] == answer[j]) { 6 continue loop1; // かぶっていたら外側のループの最初に戻る 7 } 8 } 9 i++; // かぶっていないときだけ次に進む 10}

投稿2015/01/10 00:33

argius

総合スコア9390

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

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

code_red_sky928

2015/01/10 03:19

実は for (int j = i - 1; j >= 0; j--)この処理がよくわからなかったのですが具体的な数値で考えるとよくわかりました。argius様のコードのほうが簡潔でわかりやすくて理解しやすかったです。回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問