- ベストアンサー
Java配列のソートについて
- Javaの配列のソートについて勉強中の質問です。指定のコードについて先輩プログラマーに教えてもらいたいです。
- 特に、2回目のtest.length-1の-1の役割について教えてください。
- また、配列のソートが苦手でコツを知りたいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
以下の解説では, if (test[t] > test[s]) { ではなく, if (test[s] < test[t]) { と読み替えてください。 外側のfor文のループ変数sを左項, 内側のfor文のループ変数tを右項 に置いた方が説明がしやすいように思うので。 -------- 配列の要素数=5 を想定する。 test.length=5 で,配列要素の添字は test[0]~test[4] まで。 ▼外側のループ1回目。s=0 のとき。 内側のループは for(int t=s+1; t<test.length;t++){ なので test[0] < test[1] ならば両者を交換 test[0] < test[2] ならば両者を交換 test[0] < test[3] ならば両者を交換 test[0] < test[4] ならば両者を交換 結果的にtest[0]に最も大きな値が格納される ▼外側のループ2回目。s=1 のとき。 内側のループは for(int t=s+1; t<test.length;t++){ なので test[1] < test[2] ならば両者を交換 test[1] < test[3] ならば両者を交換 test[1] < test[4] ならば両者を交換 結果的にtest[1]に2番目に大きな値が格納される ▼外側のループ3回目。s=2 のとき。 内側のループは for(int t=s+1; t<test.length;t++){ なので test[2] < test[3] ならば両者を交換 test[2] < test[4] ならば両者を交換 結果的にtest[2]に3番目に大きな値が格納される ▼外側のループ4回目。s=3 のとき。 内側のループは for(int t=s+1; t<test.length;t++){ なので test[3] < test[4] ならば両者を交換 結果的にtest[3]に4番目に大きな値が格納される -------- ここまででtest[0]~test[3]の値が順に決定したので, 残ったのはtest[4]ただ一つだけであり, 必然的にそれは最小値として決定することになる。 上記の▼を見直すと,sの値は0~3まで変化すればよいことが分かる。 よって,外側のfor文のループ継続条件は, s < test.length(数値を当てはめると s < 5 )ではなく, s < test.length - 1(数値を当てはめると s < 4 )となる。 -------- > 配列のソートがどうしても苦手です。 > 何かソートを理解するのにコツみたいなものがあれば、ご教授ください。 「計算機になったつもりで,具体的な数値を使って処理を実行」(回答No.1) を試みてみた,上記の数値の書き下し解説を読んでみて理解できましたか? もしも,上記を読んでみて理解できたのなら, 質問者は「配列のソートがどうしても苦手」というのではなく, メンドクサがって上記のような数値の書き下しを試してこなかった可能性があります。 想定する要素数は,片手で数えられる程度の少量でも十分です。 頭の中だけで流れを追うのではなく,変数の変化を逐一,紙に書き下してください。 それを何十回と繰り返して訓練していくと, 変数の変化の下限・上限をどう決めればよいか が直感的に見えてくるコツが体得できると思います。
その他の回答 (3)
- root139
- ベストアンサー率60% (488/809)
> 2回目のtest.length-1の-1はどういった役割を果たしてるんでしょうか? 無駄なループを防ぐためです。 -1が無くても結果は変わりません。 s = test.length - 1 の状態でforの内側を実行しても、t は s + 1 で初期化されて t < test.length が成り立たないので、内側のループは一度も実行されずに終わります。 > 何かソートを理解するのにコツみたいなものがあれば、ご教授ください。 ソートに限らず、コードが理解できない場合は、コンピュータになったつもりで1行1行動作をシミュレートしてみると良いでしょう。 また、print 文を各所に追加して、各段階の変数の状態や動作を表示させるのも理解に役立つでしょう。 例) ------------------------------------------ for (int i = 0; i < test.length; i++) { String str = br.readLine(); test[i] = Integer.parseInt(str); } System.out.println(java.util.Arrays.toString(test)); System.out.println(); for (int s = 0; s < test.length - 1; s++) { for (int t = s + 1; t < test.length; t++) { System.out.println((s + 1) + "番目と" + (t + 1) + "番目を比較"); if (test[t] > test[s]){ int tmp = test[t]; test[t] = test[s]; test[s] = tmp; System.out.println((s + 1) + "番目の「" + test[s] + "」と" + (t + 1) + "番目の「" + test[t] + "」を交換"); } System.out.println(java.util.Arrays.toString(test)); } System.out.println(); } System.out.println(java.util.Arrays.toString(test)); ----------------------------------------------
お礼
なるほど!無限なループを防ぐためにあるんですね! わからなかった点が理解できました! 回答ありがとうございます。
- yukichance
- ベストアンサー率13% (9/67)
-1で、引数同士、かぶらんよ。 もっとも、ソートしたいだけならば、 ソート関数が簡単です。 y=x.sort(); //x:ソート対象配列名 //y:ソート目的配列名
お礼
回答ありがとうございます。 ソート関数を学んでみます。 アドバイスありがとうございます。
- f272
- ベストアンサー率46% (8576/18354)
「2回目のtest.length-1の-1」って言うけどtest.length-1は1回しか出てこないよ。 それでそれがs=test.lengthだったらt=s+1だからt=test.length+1からループが始まることになって,このループの意味がなくなるよね。 > 何かソートを理解するのにコツみたいなものがあれば、ご教授ください。 自分が計算機になったつもりで,具体的な数値を使って処理を実行してみる。
お礼
回答ありがとうございます。 とにかく色々な処理を実行してみることが大切なんですね!
お礼
とてもわかりやすく説明してくださってありがとうございます。 やはり色々なパターンを繰り返すことが大切なんですね! 回答ありがとうございます。