C++ 複数入力。defineの使い方からバブルソートとセレクションソートなどの並び替え
バブルソート
複数入力をするとどうなるのか
要はこれです。どうなるのか
int main() { string a; int b; cin >> a >> b; cout << a << endl; cout << b << endl; return 0; }
実行結果
普通にEnterを押して複数個入力できるようです。
意外と楽ですね。
ソート人数の設定
一つの方法として#defineを使って最初に人数を定義しておく。
こんな感じ
#include<iostream> #include<string> #define NUM 5 using namespace std; int main() { return 0; }
こうすることでNUMが5という値になります。データの数を先に決めておく的な。
実行結果出すまでもないので・・・
最初にNUMをすることで、この後のプログラムを書く際にNUMの定義を変えれば人数を変えれることになります。柔軟になるということですね。
とりあえずこのままバブルソートへ
まずはNUM回の入力から。名前も入れましょうか。
#include<iostream> #include<string> #define NUM 5 using namespace std; int main() { string name[NUM]; int score[NUM]; for (int i = 0; i < NUM; i++) { cout << i + 1 << "人目の名前を入力してください" << endl; cin >> name[i]; cout << i + 1 << "人目の点数を入力してください" << endl; cin >>score[i]; } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" << name[i] << " " << score[i] << endl; } return 0; }
実行結果
上手くいっていますね。
今回のソートは昇順で流していくことにしましょう。昇順ができれば降順に変える方法は簡単なので。
同時に最大・最小も出力しましょう。
以上纏めると今回やることは
- バブルソートを行い、昇順にする
- 最高点の名前・点数を出力
- 最低点の名前・点数を出力
ではまず、バブルソートから
#include<iostream> #include<string> #define NUM 5 using namespace std; int main() { string name[NUM]; int score[NUM]; for (int i = 0; i < NUM; i++) { cout << i + 1 << "人目の名前と点数を入力してください" << endl; cin >> name[i]; cin >>score[i]; } for (int i = 0; i < NUM; i++) { for (int j = NUM - 1; j > i; j--) { if (score[j-1]>score[j]) { int a = score[j - 1]; score[j - 1] = score[j]; score[j] = a; string b = name[j - 1]; name[j - 1] = name[j]; name[j] = b; } } } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" << name[i] << " " << score[i] << endl; } return 0; }
実行結果
上手くいっていますね。
次は最大最小です。
といっても簡単で、これは最大・最小が更新されるたびにその[i]の値を残しておけばいいでしょう。
int型でmaxindexとminindexを宣言します。初期値を0にすることで、データが1個の時の最大値・最小値は1人目の点数になります。
#include<iostream> #include<string> #define NUM 5 using namespace std; int main() { string name[NUM]; int score[NUM]; int maxindex = 0; int minindex = 0; for (int i = 0; i < NUM; i++) { cout << i + 1 << "人目の名前と点数を入力してください" << endl; cin >> name[i]; cin >>score[i]; if (score[i] > score[maxindex]) { maxindex = i; } if (score[i] < score[minindex]) { minindex = i; } } cout << "最高点は" << name[maxindex] << " " << score[maxindex]<<endl; cout << "最低点は" << name[minindex] << " " << score[minindex]<<endl; for (int i = 0; i < NUM; i++) { for (int j = NUM - 1; j > i; j--) { if (score[j-1]>score[j]) { int a = score[j - 1]; score[j - 1] = score[j]; score[j] = a; string b = name[j - 1]; name[j - 1] = name[j]; name[j] = b; } } } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" << name[i] << " " << score[i] << endl; } return 0; }
実行結果
上手くいっていますね
乱数を使ってデータを入力する。
なんだか、AさんとかBさんとか毎回入力するのもバカバカしくなってきたので、ここも自動でやってもらいます。
C++にforeachのような構文があるのかよくわからないので、ここは配列を普通に使用してrandを使えば勝手に名前と点数を入れてくれるかな。
#include<iostream> #include<string> #define NUM 5 using namespace std; int main() { string name[NUM] = { "A","B","C","D","E" }; int score[NUM]; int maxindex = 0; int minindex = 0; for (int i = 0; i < NUM; i++) { cout << name[i] << "さんの点数:"; score[i] = (rand() % 100) + 1; cout << score[i] << endl; if (score[i] > score[maxindex]) { maxindex = i; } if (score[i] < score[minindex]) { minindex = i; } } cout << "最高点は" << name[maxindex] << " " << score[maxindex]<<endl; cout << "最低点は" << name[minindex] << " " << score[minindex]<<endl; for (int i = 0; i < NUM; i++) { for (int j = NUM - 1; j > i; j--) { if (score[j-1]>score[j]) { int a = score[j - 1]; score[j - 1] = score[j]; score[j] = a; string b = name[j - 1]; name[j - 1] = name[j]; name[j] = b; } } } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" << name[i] << " " << score[i] << endl; } return 0; }
実行結果
随分と楽になりました。
ここから先は名前とかどうでもいい(大学などで課題で出る場合は必要なのでしょうが)ので、点数のみでソートをかけることにしましょう。コードも少し長くなって見づらくなってきたので。
NUM 10に変更し
nameを消しました。
#include<iostream> #include<string> #define NUM 10 using namespace std; int main() { int score[NUM]; for (int i = 0; i < NUM; i++) { score[i] = (rand() % 100) + 1; cout<< i+1 <<":"<< score[i] << endl; } cout << endl; for (int i = 0; i < NUM; i++) { for (int j = NUM - 1; j > i; j--) { if (score[j-1]>score[j]) { int a = score[j - 1]; score[j - 1] = score[j]; score[j] = a; } } } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" <<score[i] << endl; } return 0; }
実行結果
いい感じですね。
それではセレクションソートへ。
セレクションソート
これは、最小(又は最大)の選び出し、昇順ならば一番上に吹っ飛ばし、次は一番上以外の数字の中で最小の数を探し、二番目にぶっ飛ばすソートです。
先ほどと同様、minindexを導入しましょう。
内部ループ(jのループ)では直接のデータ交換は無しです。あくまで最小の値を持つindexを保存するだけです。
外部ループ(iのループ)でデータを交換してください。
#include<iostream> #include<string> #define NUM 10 using namespace std; int main() { int score[NUM]; int minindex; for (int i = 0; i < NUM; i++) { score[i] = (rand() % 100) + 1; cout<< i+1 <<":"<< score[i] << endl; } cout << endl; for (int i = 0; i < NUM; i++) { minindex = i; //初期化 for (int j = i; j < NUM; j++) { if (score[minindex] > score[j]) { minindex = j; } } int a = score[i]; score[i] = score[minindex]; score[minindex] = a; } for (int i = 0; i < NUM; i++) { cout << i + 1 << ":" <<score[i] << endl; } return 0; }
実行結果
と、セレクションソートでした。
次はNUMの値を任意に変えても繰り返せるようになりたいですね。