プログラム 技術

様々な言語で中央値を求める(C、C++、C#、PowerShell)

値集計していた際に中央値を求めたいことがあり、既存のプログラム関数として用意されている(Excel関数にはある)と思っていたのですが自前で作る必要があったため備忘録としてここに残します

中央値の求め方

配列またはリストの要素数が奇数の場合、その配列の真ん中になります
配列またはリストの要素数が偶数の場合、その配列の真ん中にあたる値とその隣の値の平均になります
文字だけだとわからないので各言語での中央値の求め方を紹介します

C言語で中央値を求める

C言語にはC#等でいうところのリストというもはないので配列のみとなります
また、ソート関数も一応既存のものであるのですが今回は自前のクイックソート関数を使用します
クイックソートについては以下のサイトを参照してください

参考サイト
クイックソートを図を使って分かりやすく解説(C言語サンプルプログラム付き) | だえうホームページ
クイックソートを図を使って分かりやすく解説(C言語サンプルプログラム付き) | だえうホームページ

このページではソートとクイックソートについて解説し、さらにC言語でクイックソートを実装したプログラムとそのプログラムの説 ...

続きを読む

double FindMedian(int values[], unsigned int num) {
    double median = 0.0f;

    // 配列の要素数が偶数であるかどうかを判断
    if (num % 2 == 0) {
        // 配列の要素数が偶数の場合は中央の2つの値の平均を中央値とする
        median = (double)(values[num / 2] + values[num / 2 - 1]) / 2;
    }
    else {
        // 値の数が奇数個の場合は中央の値そのものを中央値とする
        median = values[num / 2];
    }
    return median;
}

// 要素数が奇数の場合
int oddNumberValues[] = { 9, 2, 3, 10, 7 };
unsigned int oddNum = sizeof(oddNumberValues) / sizeof(oddNumberValues[0]);
QuickSort(oddNumberValues, 0, oddNum - 1);
double median = FindMedian(oddNumberValues, oddNum);
printf("MEDIAN = %f\n", median);   // 7

// 要素数が偶数の場合
int evenNumberValues[] = { 100, 200, 150, 250, 50, 5 };
unsigned int evenNum = sizeof(evenNumberValues) / sizeof(evenNumberValues[0]);
QuickSort(evenNumberValues, 0, evenNum - 1);
median = FindMedian(evenNumberValues, evenNum);
printf("MEDIAN = %f\n", median);   // 125

C++で中央値を求める

C++ではリストといってもいくつか種類があるので今回はvectorから中央値を求めます
配列は上記のC言語で実施したのでこちらには記載しません

double FindMedian(std::vector<int> vec) {
    double median;
    int num = vec.size();
    // 昇順でソート
    std::sort(vec.begin(), vec.end());

    if (vec.size() % 2 == 0) {
        median = (double)(vec[num / 2] + vec[num / 2 - 1]) / 2;    
    }
    else {
        median = (double)vec[num / 2];
    }

    return median;
}

// 要素数が奇数の場合
std::vector<int> oddNumber;
oddNumber = { 55, 21, 13, 60, 34, 90, 76 };
double median = FindMedian(oddNumber);
printf("MEDIAN = %f\n", median);    // 55

// 要素数が偶数の場合
std::vector<int> evenNumber = { 15, 31, 77, 61, 23, 33 };
median = FindMedian(evenNumber);
printf("MEDIAN = %f\n", median);    // 32

C#で中央値を求める

リストの中央値を求めます

private double FindMedianList(List<int> _list)
{
    double median = 0.0f;
    int num = _list.Count;

    // 昇順でソート
    _list.Sort();

    if(num % 2 != 0)
    {
        median = (double)_list[num / 2];
    } 
    else
    {
        median = (double)(_list[num / 2] + _list[num / 2 - 1]) / 2;
    }

    return median;
}

// 要素数が奇数の場合
var oddNumber = new List<int>() { 100, 20, 200, 150, 130};
var median = FindMedianList(oddNumber);
Console.WriteLine($"MEDIAN = {median}");   // 130

// 要素数が偶数の場合
var evenNumber = new List<int>() { 3, 9, 1, 2, 7, 5 };
median = FindMedianList(evenNumber);
Console.WriteLine($"MEDIAN = {median}");   // 4

PowerShellで中央値を求める

最後にPowerShellの配列から中央値を求めます

function Find_Median([Array]$_arr) {
    $median = 0.0
    $num = $_arr.Length

    # 昇順でソート
    $_arr = $_arr | Sort-Object

    if($num % 2 -ne 0) {
        $median = $_arr[$num / 2]
    } else {
        $median = ($_arr[$num / 2] + $_arr[$num / 2 - 1]) / 2
    }

    return $median;
} 

# 要素数が奇数の場合
$oddNumber = @(1000, 2000, 1500, 2500, 1250)
$median = Find_Median -_arr $oddNumber
Write-Host "MEDIAN = $median"   # 1500

# 要素数が偶数の場合
$evenNumber = @(80, 20, 10, 50, 30, 70)
$median = Find_Median -_arr $evenNumber
Write-Host "MEDIAN = $median"   # 40

-プログラム, 技術
-, , ,