中央値・最小値・最大値
簡単な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のコンソール画面出力に対応していることがわかる。
演算子 << による出力において、出力の形式を制御(書式制御)することができる。このことについて説明したウェブサイトも用意している。