中央値・最小値・最大値
簡単なC++サンプルプログラム
なお、C++の説明を<岡本安晴「大学生のための心理学VC++プログラミング入門」>で行っている。
中央値などの順序統計量に関する説明を<岡本安晴「データ分析のための統計学入門」、pp. 22-24,53>で行っている。
幾つかのデータが与えられたとき、その最小値・中央値・最大値を求める。例えば、5個のデータ
3 7 4 9 6
が与えられているとする。これを大きさの順に並べると
3 4 6 7 9
となるので、最小値は3、中央値は6、最大値は9である。
4個のデータ
5 7 3 8
の場合は、大きさの順に並べると
3 5 7 8
となるので、最小値は3、最大値は8となる。中央値は、ちょうど真ん中の順位に当たる数がないので、真ん中にあたる位置の左右の数、5と7、の平均値 を中央値とする。
一般にN個のデータ、、・・・、、に対して、それを大きさの順に並べ直したものを
、・・・、、・・・、
とおく。
である。このとき、
最小値=
最大値=
である。
中央値は、Nが奇数であるか、偶数であるかに応じて以下のように与えられる。
のとき
中央値=
のとき
中央値=
中央値・最小値・最大値を求めるときには、データを大きさの順に並べると求めやすい。大きさの順に並べる簡単な方法として単純整列法がある。これは、例えば次のコードによって行える。
for
(int i = 0; i < n - 1; i++) {
int
j = i;
for
(int k = i; k < n; k++) {
if
(x[k] < x[j]) j = k;
}
if
(i < j) {
double
v = x[i];
x[i]
= x[j]; x[j] = v;
}
}
上のコードでは、n個のデータ、x[0]、・・・、x[n-1]、から、まず一番小さい値を探して、それをx[0]と入れ替えている。
次に、この入れ替えた最小のデータx[0]を除いたx[1]、・・・、x[n-1]から最小のものを探して、それをx[1]と入れ替えている。
この手順をx[n-2]まで繰り返すと、x[0]、・・・、x[n-1]は小さいものから大きいものまで順に並べたものとなる。
上の単純整列法を用いて、中央値・最小値・最大値を求めるプログラム例を以下のように作成した。
プログラム3.1
#include <iostream>
#include <fstream>
using namespace std;
void sort_data(double * x, int n) {
for
(int i = 0; i < n - 1; i++) {
int
j = i;
for
(int k = i; k < n; k++) {
if
(x[k] < x[j]) j = k;
}
if
(i < j) {
double
v = x[i];
x[i]
= x[j]; x[j] = v;
}
}
return;
}
int main() {
double
data[1000];
cout
<< "入力データファイル = ";
char
fin_name[100];
cin
>> fin_name;
ifstream
fin(fin_name);
int
n = 0;
while
(true) {
fin
>> data[n];
if
(fin.fail()) break;
n++;
}
fin.close();
cout
<< "データ..."
<< endl;
for
(int i = 0; i < n; i++)
cout
<< " "
<< data[i] << endl;
sort_data(data,
n);
cout
<< "整列データ..." << endl;
for
(int i = 0; i < n; i++)
cout
<< " "
<< data[i] << endl;
double
max_v = data[n - 1], min_v = data[0];
double
med;
if
((n % 2) == 0) {
med
= (data[(n / 2) - 1] + data[n / 2]) / 2.0;
}
else
{
med
= data[n / 2];
}
cout
<< "最小値
= " << min_v << endl;
cout
<< "中央値
= " << med << endl;
cout
<< "最大値
= " << max_v << endl;
char
ck;
cin
>> ck;
return
0;
}
上のプログラムを実行するとコンソール画面が表示され、入力データファイル名の設定が求められる(図1)。
図1
入力データファイルは図2のようにテキストファイルとして用意しておき、プログラム・ソース・コード・ファイルと同じフォルダに置いておく。
図2
入力データファイル名を設定する(図3)。
図3
入力データセット名を設定後、Enterキーを押すと、データが読み込まれて計算が行われ、コンソール画面に表示される(図4)。
図4
データは次のwhile文によって読み込まれている。
while
(true) {
fin
>> data[n];
if
(fin.fail()) break;
n++;
}
データがすべて読み込まれると、次の読み込みで fail() の値が true になるので、次のコード
fin
>> data[n];
if
(fin.fail()) break;
の実行によって、while 文を抜け出す。
図4の画面では、文字の入力待ちとなっている。これは次のコード
char
ck;
cin
>> ck;
による。何か文字キーを押してEnterキーを押すと
cin
>> ck;
の実行終了となり、次の return 文が実行されてプログラムの終了となる。
上のプログラム3.1では、出力はコンソール画面である。ファイルに出力するプログラムとして次のものを用意した。
プログラム3.2
#include <iostream>
#include <fstream>
using namespace std;
void sort_data(double * x, int n) {
for
(int i = 0; i < n - 1; i++) {
int
j = i;
for
(int k = i; k < n; k++) {
if
(x[k] < x[j]) j = k;
}
if
(i < j) {
double
v = x[i];
x[i]
= x[j]; x[j] = v;
}
}
return;
}
int main() {
double
data[1000];
cout
<< "入力データファイル = ";
char
fin_name[100];
cin
>> fin_name;
ifstream
fin(fin_name);
cout
<< "出力ファイル = ";
char
fout_name[100];
cin
>> fout_name;
ofstream
fout(fout_name);
fout
<< "入力データファイル..." << fin_name << endl << endl;
int
n = 0;
while
(true) {
fin
>> data[n];
if
(fin.fail()) break;
n++;
}
fin.close();
fout
<< "データ..."
<< endl;
for
(int i = 0; i < n; i++)
fout
<< " "
<< data[i] << endl;
sort_data(data,
n);
fout
<< "整列データ..." << endl;
for
(int i = 0; i < n; i++)
fout
<< " "
<< data[i] << endl;
double
max_v = data[n - 1], min_v = data[0];
double
med;
if
((n % 2) == 0) {
med
= (data[(n / 2) - 1] + data[n / 2]) / 2.0;
}
else
{
med
= data[n / 2];
}
fout
<< "最小値
= " << min_v << endl;
fout
<< "中央値
= " << med << endl;
fout
<< "最大値
= " << max_v << endl;
fout.close();
cout
<< fout_name << " was saved." << endl;
char
ck;
cin
>> ck;
return
0;
}
出力がファイルへの出力であることを除いてプログラム3.1と同じである。このプログラムを実行すると、まず入力データセット名の入力が求められる(図5)。
図5
入力データセット名を設定してEnterキーを押すと、次に出力用ファイル名の設定が求められる(図7)。
図6
出力用ファイル名(テキストファイル名なので *.txt と、拡張子は .txt とする)の設定後、Enterキーを押すとデータの読み込みと計算、および計算結果のファイルへの出力が行われ、出力用ファイルが保存されたことが表示される(図7)。
図7
図7の状態で、何か文字キーを押してEnterキーを押すとプログラムの実行終了となる。出力ファイル名が図7の設定の場合、出力ファイルはプログラムのソースコードファイルと同じフォルダ(実行時カレントフォルダ)に保存される。この出力ファイルを開くと、図8のようになっている。
図8
図8のファイル出力が、図4のコンソール画面出力に対応していることがわかる。
演算子 << による出力において、出力の形式を制御(書式制御)することができる。このことについて説明したウェブサイトも用意している。