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

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

ややこしいコード

#include<iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for (int i = 0; i < num; i++) { cin >> test[i]; } for (int s= 0; s < num - 1; s++) { for (int t = s + 1; t < num; t++) { if (test[t] > test[s]) { int tmp = test[t]; test[t] = test[s]; test[s] = tmp; } } } for (int j = 0; j < num; j++) { cout << j + 1 << "番目の人の点数は" << test[j] << "です。\n"; } return 0; } 配列を並べ替える(ソート)する練習コードなんですが、 ちょっとややこしいので解りやすく教えて欲しいです。 因みに点数は、 22,80,57,60,50の順でお願いします。

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

  • ベストアンサー
  • Kaneyan-R
  • ベストアンサー率42% (1243/2894)
回答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/8248)
回答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% (1243/2894)
回答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++) ここの部分がよく解っておりません; 恥ずかしながらご教示お願いします;

関連するQ&A

  • 点数の大きい順に出力する

    #include <iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for(int i=0; i<num; i++){ cin >> test[i]; } } } } for(int j=0; j<num; j++){ cout << j+1 << "番目の人の点数は" << test[j]<< "です。\n"; } return 0; } ---------- の for(int s=0; s<num-1; s++){ for(int t=s+1; t<num; t++){ if(test[t] > test[s]){ int tmp = test[t]; test[t] = test[s]; test[s] = tmp; の部分が理解できません。 s<num-1 は 0<4; ということでしょうか? 値が5つ入力されその値が if(test[t] > test[s]){ にどの様に挿入されるのかが 解りません。  

  • ところどころ理屈の解らない記述

    #include<iostream> using namespace std; int main() { const int num = 5; //変数numを5の値で初期化、constを使うから値の変更はない int test[num]; //int型の配列testを初期化 cout << num << "人の点数を入力してください。\n"; //変数numを出力して点数入力を促す for (int i = 0; i < num; i++) { //int型のiを0で初期化 numよりiが小さい場合 iを1増やす cin >> test[i]; //上のfor文によって配列の点数を5回入力 } for (int s = 0; s < num - 1; s++) {  for (int t = s + 1; t < num; t++) { if (test[t] > test[s]) { int tmp = test[t]; test[t] = test[s]; test[s] = tmp; } } } for (int j = 0; j < num; j++) { cout << j + 1 << "番目の人の点数は" << test[j] << "です。\n"; } return 0; } 解るところは、コメントしてあります。 それ以外で解らないところがあるので、(特にnumの後ろにつく-1の意味が解らない) どうかご回答お願いします。

  • 設定した値が意図せぬ値に

    POJ 3176の問題です。 http://poj.org/problem?id=3176 #include <iostream> #include <algorithm> #define MAX 100 using namespace std; int main() { int n; cin >> n; int line[n-1][MAX]; int num[n-1][MAX]; cin >> line[0][0]; if(n==0) { cout << 0 <<endl; return 0; } else if(n==1) { cout << line[0][0] << endl; return 0; } for (int i =1;i < n;i++) { for (int j=0;j < i+1;j++) { int x; cin >> x; line[i][j]= x; } } for (int k= 0 ; k<n;k++) { num[n-1][k]= line [n-1][k]; } for (int k= n-2; k > 0 ; k--) { for (int l=0 ; l<k+1; l++) { num[k][l] = max (num[k+1][l],num[k+1][l+1]) + line[k][l]; } } num[0][0] = max(num[1][0],num[1][1]) + line[0][0]; cout << line[0][0] <<" "<<num[0][0]<<endl; return 0; } 入力 4 3 1 3 1 2 3 1 3 4 5 出力 1 12 最後に出力でline[0][0]をするようにしているのはバグチェックのためです。 ここで僕がわからないのはどうしてline[0][0]が3で宣言し、ほかでいじっていないにも関わらず、最後に1になっているのかということです。 どなたかわかる方がいらっしゃったらよろしくお願いします。

  • 点数の最高得点を知るプログラム

    #include<iostream> using namespace std;  int main() {  int i;  int box[5]; cout << "テストの点数を入力してください。\n"; for (int i = 0; i < 5; i++) { cin >> box[i]; } return 0; } for文で 点数を入力まで行ったのですが、 関数で配列を使って入力した最大値を調べるプログラムの練習問題なんですが、 何回もエラー出てしまいよく解っていません。 関数からポインタまで配列でどうつかうかがよく解ってないんだと思います。 良かったら教えてください、お願いします。

  • 配列のプログラムですが

    #include <iostream> using namespace std; int main() { int a[100],b=-9999; int i=0,j; do { cout << "整数値を入力してください\n"; cin >> a[i]; b += a[i]; i++; }while( a[i-1] != 9999); cout << b << '\n'; for(j=0;j<i-1;j=j+1) cout << a[j] * 3 << '\n'; return 0; } このプログラムってどんな計算をしてるんですか?誰か分かる人いますか 整数値を入れてくださいって出るだけなんですが

  • icpcの過去問

    問題→ http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1147&lang=jp 自分の回答→ #include <iostream> using namespace std; int numbers[105]; int order(int n,int num){ if(num==0){numbers[0]=n;} else{ for(int i=0;i<num;i++){ if((numbers[num-(i+1)])>n){//cout << "here1"; numbers[num-i]=numbers[num-(i+1)];//cout << "here2"; numbers[num-(i+1)]=n;//cout << "here3"; } } } return 0; }//昇順に並べる int main(){ int n; while(cin>>n,n){ int count,answer; for(int i=0;i<n;i++){int Numb; cin >> Numb;if(i==2){cout << "here";} order(Numb,i); count++; }//昇順に要素が並んだ for(int i=1;i<count-1;i++){ answer += numbers[i]; } answer = answer/(count-2); cout << answer << endl; } } 実行結果→ 3 7 6 5 Bus error となってしまいます。最後の入力の時に、cinされずにbuserrorになるのですがなぜなのでしょうか。

  • 素数

    Limit以下の素数をすべて表すプログラムなんですが実行した結果 ________________________________ Input Upper Limit:11 s[0]=3 s[1]=5 s[2]=5 s[3]=5 s[4]=7 s[5]=7 s[6]=7 s[7]=7 s[8]=7 s[9]=9 となるんですが s[0]=3 s[1]=5 s[2]=7 s[3]=9 にしたいですがどうすればいいのでしょうか? 教えてください。 ________________________________ #include<iostream> using namespace std; int main(void) { int Limit; int i,j,n; int s[256]; n=0; cout<<"Input Upper Limit:"; cin>>Limit; for(i=1;i<Limit;i++) { for(j=2;j<i;j++) { if(i%j==0) break; s[n]=i; cout<<"s["<<n<<"]="<<s[n]<<"\n"; n++; } } return 0; }

  • 合計値を求める関数

    #include<iostream> using namespace std; //sum関数の定義 int sum(int x, int y) { return x + y;  } int main() { int num1, num2, ans; cout << "1番目の整数を入力して下さい。\n"; cin >> num1; cout << "2番目の整数値を入力して下さい。\n"; cin >> num2; ans = sum(num1, num2); cout << "合計は" << ans << "です。\n"; return 0; }  ここのreturn x+y;の所の合計値を戻り値として返す処理の仕組みを解りやすく教えて欲しいです、戻り値はちょっと解りづらいです、よろしくお願いします。

  • 配列を使った入力

    配列を使った入力 下記プログラムで sample9.4.cpp: function 内の `int main()': sample9.4.cpp:18: no match for `std::istream& << int&' operator というエラーがでてしまいます。 たぶん test[b][a] = c; という部分が悪いと思うのですが、 なぜ悪いのか分かりません。 配列の使い方が間違っているのでしょうか。 どなたか教えて頂けると嬉しいです。 ーー #include <iostream> using namespace std; int main() { int a,b,c,sub,num; cout << "Please input the number of subjects\n"; cin >> sub; cout << "Please input the number of people\n"; cin >> num; int test[b][a]; for(int b=0; b<sub; b++){ for(int a=0; a<num; a++){ cout << "Please input the point of the " << a+1 << "th people of the " << b+1 << "th subject\n"; cin << c; test[b][a] = c; } } for(b=0; b<sub; b++){ for(int a=0; a<num; a++){ cout << "The point of the " << a+1 << "th people of the " << b+1 << "th subject is " << test[a][b] << '\n'; } } return 0; }

  • コンパイルはできるのですが

    C++入門者です。C言語の範疇です。 コンパイルはできるのですが、実行すると ”問題が発生したため、*****.exe を終了します。 ご不便をおかけして申し訳ありません。” というウィンドウがででしまします。 どこで誤っているのかわからなくて困っています。 どなたかご教授願えないでしょうか。 どうかよろしくお願いいたします。 -----プログラム内容です。----- #include<iostream> using namespace std; int main() { char *s1 ,*s2; cin >> s1; for (int i=0;i <= strlen(s1)-1;i++) { *(s2+i) = *(s1 + strlen(s1) - 1 - i); } *(s2+strlen(s1)) = '\0'; cout << s1 << '\n'; cout << *(s2) << '\n'; return 0; } --------------------------------------

専門家に質問してみよう