Up

中央値・最小値・最大値

簡単な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のコンソール画面出力に対応していることがわかる。

 

演算子 << による出力において、出力の形式を制御(書式制御)することができる。このことについて説明したウェブサイトも用意している。

 

Up