読者です 読者をやめる 読者になる 読者になる

プログラミング メモ memo.txt

一度考えたコードを忘れるのはもったいないので、メモとして残していきます。現在、JavaとC++とVBAを勉強しているので、そこらへん書きます。

C++ 複数入力。defineの使い方からバブルソートとセレクションソートなどの並び替え

プログラミング C++

f:id:rkprog:20151024010640p:plain

バブルソート

f:id:rkprog:20151023034405p:plain

複数入力をするとどうなるのか

要はこれです。どうなるのか

int main()
{
	string a;
	int b;
	cin >> a >> b;
	cout << a << endl;
	cout << b << endl;

	return 0;
}


実行結果

f:id:rkprog:20151023025932p:plain

普通に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;
}

実行結果

f:id:rkprog:20151023031103p:plain

上手くいっていますね。

今回のソートは昇順で流していくことにしましょう。昇順ができれば降順に変える方法は簡単なので。

同時に最大・最小も出力しましょう。

以上纏めると今回やることは

  • バブルソートを行い、昇順にする
  • 最高点の名前・点数を出力
  • 最低点の名前・点数を出力


ではまず、バブルソートから

#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;
}

実行結果

f:id:rkprog:20151023031808p:plain


上手くいっていますね。

次は最大最小です。
といっても簡単で、これは最大・最小が更新されるたびにその[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;
}

実行結果

f:id:rkprog:20151023032915p:plain

上手くいっていますね

乱数を使ってデータを入力する。

なんだか、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;
}

実行結果

f:id:rkprog:20151023033651p:plain

随分と楽になりました。

ここから先は名前とかどうでもいい(大学などで課題で出る場合は必要なのでしょうが)ので、点数のみでソートをかけることにしましょう。コードも少し長くなって見づらくなってきたので。

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;
}

実行結果

f:id:rkprog:20151023034405p:plain

いい感じですね。

それではセレクションソートへ。

セレクションソート

これは、最小(又は最大)の選び出し、昇順ならば一番上に吹っ飛ばし、次は一番上以外の数字の中で最小の数を探し、二番目にぶっ飛ばすソートです。

先ほどと同様、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;
}

実行結果

f:id:rkprog:20151023035149p:plain


と、セレクションソートでした。

次はNUMの値を任意に変えても繰り返せるようになりたいですね。