• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ややこしいコード)

配列を並べ替えて点数を表示する

このQ&Aのポイント
  • C++のコードを使用して、与えられた配列の要素を並べ替え、点数を表示する方法を説明します。
  • 要素をソートするには、選択ソートアルゴリズムを使用します。
  • 与えられた点数配列[22,80,57,60,50]を昇順にソートし、結果を表示します。

質問者が選んだベストアンサー

  • ベストアンサー
  • Kaneyan-R
  • ベストアンサー率42% (1370/3193)
回答No.4

〉for (int s= 0; s < num - 1; s++) 〉for (int t = s + 1; t < num; t++) 外側のforループは何個目を比較元にするかのループです。 初期値か「0」ですからtest[0]、つまり配列testの一番目からスタートすることになります。 繰り返す回数は「num-1」なので、numの値である5から1引いた4未満(s<4)、増分値はインクリメント(s++)なので1ですから、0~3の4回繰り返すことになります。 なぜ配列は5個(0~4)なのに、num-1で4にしているかと言うと、配列の5番目は最後なので、比較する次の値がありません。よって比較する必要が無いためです。 内側のforループは、比較先が何個目かを決めるループです。 初期値は「s+1」ですから、比較元の一つ隣になります。 繰り返す回数は「num」ですから5未満。 ここでアレ?って思いませんか? さっきは「num-1」でしたよね? 理由は簡単です。比較先は「s+1」なのですから、上限も「num-1+1」。つまり「num」となります。 ループがスタートすると 一回目はs=0 t=s+1=1を比較。 test[1]>test[0]なら、二つの値を入れ替えます。 次にtがインクリメントし s=0 t=1+1=2となり、test[0]とtest[2]を比較。 test[2]>test[0]なら、入れ替えます。 これを上限(5未満)、つまりtest[4]まで比較します。 これで「配列の一番目に一番大きい数字をもってくる」ことになります。 内側のループが最後まで行ったら、今度はsがインクリメントしs=0+1=1、内側のループは初期値t=s+1=2から再びスタートします。 よって今度は、test[1]とtest[2]~[4]を比較することになり、「配列の二番目に二番目に大きい数字をもってくる」ことになります。 これをsが上限の(4未満=3)まで繰り返すことで、「配列の四番目に四番目に大きい数字をもってくる」ことによって、「五番目は一番小さい数字」になります。

7b0m1z4c
質問者

お礼

回答ありがとうございます 非常に複雑でしたが何とか理解しました; 詳しく細かく懇切丁寧に教えて頂きありがとうございました!!

その他の回答 (5)

  • bunjii
  • ベストアンサー率43% (3589/8249)
回答No.6

>配列を並べ替える(ソート)する練習コードなんですが、 >ちょっとややこしいので解りやすく教えて欲しいです。 回答No.1のお礼に下記のような記述があります。 ----------ここから---------- 正直に申しますと、 for (int s= 0; s < num - 1; s++) for (int t = s + 1; t < num; t++) ここの部分がよく解っておりません; ----------ここまで---------- この部分と言われてもforループ基本的な動作は理解されていますよね? forループの中にforループがある理由が分からないのでしょうか? 配列変数の各要素の値をソートするときはforループの入れ子構造(多重構造)はありふれた手法なのでややこしいことではありません。 寧ろ、ループの中で値の比較と入れ替えをどのようにしているかを理解する必要があるでしょう。 配列変数のtestは5個の箱が連結していると考えれば其々の箱に番号は付いています。(test[0]、test[1]、test[2]、test[3]、test[4]) これを順番に比較対象にするためには[]内の番号を順次入れ替えて比較すれば同じ数式で繰り返すことでプログラムを簡素化できます。 test[1]>test[0]のときtest[1]をtmpへ代入し、test[0]をtest[1]へ代入し、tmpをtest[0]へ代入すればtest[1]とtest[0]を入れ替えたことになります。 この操作をtest[t]とtest[s]と言う形に置き換えればsとtの値を順次変更しながら配列変数内の値を大きい順に並べ変えられます。 sとtの値を順次変化させる手法としてforループを2重に設けてすべての組み合わせをチェックして並び替えています。 外側のforループは変数がsで0から3までの4回繰り返します。 内側のforループは変数がtでs+1から4までの繰り返しですがs=0のときはtが1から4まで4回、S=1のときはtが2から4まで3回、s=2のときはtが3から4まで2回、s=3のときはtが4だけの1回で合計10回の比較が行われます。 これらの動作の内、何がややこしいのでしょう?

7b0m1z4c
質問者

お礼

回答ありがとうございます。 ちょっとfor文の値を勘違いしていたみたいです。 for (int t = s + 1; t < num; t++) の所のs+1の所を最初の所がsの部分が1だと思ってました・・・;

回答No.5

sを使ったループで何をしたいかというと、sより前の要素がソート済みになっているようにしたいのです。 そう仮定すると、s以降の要素について処理するだけですみます。 で、s以降の要素をどうするといいかというと、その中で最も小さい要素がsの位置に来るように並べ替えればいいのです。これがtを使ったループで行っている処理です。 それがうまくいったら、sを1つずらして同じ作業を繰り返します。

7b0m1z4c
質問者

お礼

回答ありがとうございます。

  • Kaneyan-R
  • ベストアンサー率42% (1370/3193)
回答No.3

22,80,57,60,50 一個目と比較 80>22? Y 80,22,57,60,50 57>80? N 80,22,57,60,50 60>80? N 80,22,57,60,50 50>80? N 80,22,57,60,50 入れ替え結果 80,22,57,60,50 二個目と比較 57>22? Y 80,57,22,60,50 60>57? Y 80,60,22,57,50 50>60? N 80,60,22,57,50 入れ替え結果 80,60,22,57,50 三個目と比較 57>22? Y 80,60,57,22,50 50>57? N 80,60,57,22,50 入れ替え結果 80,60,57,22,50 四個目と比較 50>22? Y 80,60,57,50,22 入れ替え結果 80,60,57,50,22 結果 一番目80 二番目60 三番目57 四番目50 五番目22

7b0m1z4c
質問者

お礼

回答ありがとうございます。

回答No.2

こっちだったのね^^ for (int s= 0; s < num - 1; s++) for (int t = s + 1; t < num; t++) で、ここのnumは宣言で、5と書いてあります。 const int num = 5; なので、 for (int s= 0; s < 5 - 1; s++) for (int t = s + 1; t < 5; t++) と展開されます。 1つ目のFORループは、5-1なので、4未満 2つ目のFORループはそれに1を足したもの3+1つまり、最大4が入ってます。 なぜ、1つずらすかというと、先ほど書いた int tmp = test[t]; test[t] = test[s]; test[s] = tmp; ここに関係します。 t==sだと、同一配列を表すので、別の場所と比較する必要があるからです。 例えば、 if (test[t] > test[s]) { これの時、t==sだと、 if (test[0] > test[0]) { と、同じものを比較する無意味なコードを作り出すためです。

7b0m1z4c
質問者

お礼

回答ありがとうございます。

回答No.1

バブルソートか。なつかしい! int tmp = test[t]; test[t] = test[s]; test[s] = tmp; ここが、わかればほとんど大丈夫かと思います。 test[t] と test[s]の中身が入れ替わる ってことだけが、一番大きいポイントです。 で、 if (test[t] > test[s]) { ここが、条件、大きい順や、小さい順にすることを 決めてるのが、ここです。 >22,80,57,60,50の順でお願いします。 別に数字はなんでもOKですよ。 これバブルソートなので、どんな値が来ても、 必ずソートされますので。

7b0m1z4c
質問者

お礼

回答ありがとうございます。 正直に申しますと、 for (int s= 0; s < num - 1; s++) for (int t = s + 1; t < num; t++) ここの部分がよく解っておりません; 恥ずかしながらご教示お願いします;