/* Part8 演習問題5 */
/* 成績データの中央値(メディアン) */
#include <stdio.h>
void sort(int [], int) ;

int main(void)
{
  int score[100],n ;
  double median ;      /* 中央値 */
  FILE *fp ;
 
  fp=fopen("score.data","r") ;
  if(fp==NULL) {
    printf("ファイルのオープンに失敗しました\n") ;
    return(1) ;
  }

  n=0 ;

  while(1) {
    if(fscanf(fp,"%d",&score[n])==EOF) break ;
    if(score[n]>100) {
      printf("得点 %d は満点を超えていますので、無視します。\n",score[n]) ;
    }
    else {
      printf("%d> %d\n",(n+1),score[n]) ;
      n++ ;
      if(n==100) {
    printf("データ数が上限に達しました(入力終了)。\n") ;
    break ;
      }
    }
  }
  fclose(fp) ;

  if(n>0) {
    sort(score,n) ;
    if((n%2)!=0) {  /* データ数は奇数 */
      median = score[(n+1)/2-1] ;
    }
    else {          /* データ数は偶数 */
      median = (double)(score[(n/2)-1]+score[(n/2)])/2 ;
    }
    printf("データ件数は %d   中央値は %5.1f です。\n",n,median) ;
  }
  else {
    printf("ファイルにデータがありません。\n") ;
  }
  return(0) ;
}

/* データの整列(挿入法) */
void sort(int data[], int n)
{
  int i,j,w ;

  for(i=1;i<n;i++) {
    w=data[i] ;
    j=i-1 ;
    while((w<data[j])&&(j>=0)) {
      data[j+1]=data[j] ;
      j-- ;
    }
    data[j+1]=w ;
  }
}

% gcc -Wall part8-5.c
% ./a.out
1> 78
2> 76
3> 65
得点 102 は満点を超えていますので、無視します。
4> 99
5> 80
6> 56
7> 81
8> 92
9> 77
10> 59
11> 60
データ件数は 11   中央値は  77.0 です。
% ./a.out
1> 78
2> 76
3> 65
4> 100
5> 99
6> 80
7> 56
8> 81
9> 92
10> 77
11> 59
12> 60
データ件数は 12   中央値は  77.5 です。

  1. 最初の例は,演習問題4と同じでデータを読み込んでいる.データ数は11の奇数であるから,整列後の中央の値(9番目に読み込んだ77)が出力される.データ数が奇数の場合は,中央値も整数であるが,偶数の場合には小数点以下もありえるので,浮動小数点型で出力している.
  2. 2番目の例は,最初の例で満点を超えている102を100に置き換えたデータを読み込んでいる.よって,データ数は12の偶数となり,整列後の6番目(10番目に読み込んだ77)および7番目(1番目に読み込んだ78)のデータを加算し,2で除算した値が中央値となる.