今週のプログラムその2
今週はデータを読んで平均と分散を計算するプログラムと、配列の簡単な使い方
ポイント
-
データは標準入力(普通はキーボード)から入力する。
データをあらかじめエディタ等で作ってファイルにいれておき、
実行時にファイルから読ませることも可能。
その場合はリダイレクションという方法を用いるのが簡単
(複数のファイルからデータを読む際はこの方法は使えない)。
具体的な方法は、解説を参照。
- とりあえず、配列とは複数の変数をひとまとめにして通し番号をつけたものだと思えばよい。配列を使うには、まず要素の数を宣言する。たとえばarrayという名前で要素数10の実数配列を宣言するには
float array[10]; (Cの場合)
real array(10) (FORTRANの場合)
とする。個々の要素は要素番号(添字)によって指定でき、普通の変数と同様に使える。
ただし、要素の番号はCでは0から、FORTRANでは1から始まるという違いがある。
従って上の例では,
Cの場合array[0]からarray[9]までの要素が作られるのに対して、
FORTRANではarray(1)からarray(10)までが作られる。
添字は計算式でもよいので、x=array[i]とかy=array(2*i)などの書きかたもできる。
配列宣言でarray[10]やarray(10)と書いたとき括弧の中は配列の要素数を表わしているのに対し、計算の途中でarray[0]やarray(1)と書いた場合にはそれぞれ配列の第0要素と第1要素(どちらも配列の先頭の要素)を表わしている。同じ括弧記号を使うので混乱しないように注意
-
program 4と6で使う入力データをファイルから入力する場合は、最初の行にデータの個数、その後は一行にひとつのデータを書く。
データ数が5個のデータファイルの例
5
1.0
1.3
1.6
1.2
4
なお、プログラム自体は
まずはC版
program 4
..................
#include< stdio.h>
/* データを読んで平均と分散を計算するプログラム1 */
main()
{
float y,av,var,sum,sum2; 使う実数変数をすべて宣言
int n,i; 使う整数変数をすべて宣言
/* 変数の初期化 */
sum=0;
sum2=0;
/* データを読みつつ、和を計算 */
scanf("%d",&n); 整数変数nに標準入力から値を読む(読み込むデータの数)
"%d" は入力が整数であることを指定。
&nは値を入れる変数がnであることを指定(&はおまじない)
for( i=1; i<=n; ++i){ この{から}までをn回くりかえす(n個のデータをよんで処理)
scanf("%f",&y); 実数変数yに値を読む
"%f" は入力が実数であることを指定。
&yは値を入れる変数がyであることを指定(&はおまじない)
sum += y; yの値を変数sumに足す
sum2 += y*y; y*y(yの2乗)を変数sum2に足す
}
av = sum/n; sum/nを変数avにいれる(データの平均値)
sum2 /= n; sum2をnで割る(データの2乗の平均値)
var = sum2-av*av; 分散を計算して変数varに入れる
/* 出力 */
printf("number of data= %d\n",n); データ数nを出力
printf("average= %f\n",av); 平均値avを出力
printf("variance= %f\n",var); 分散varを出力
}
..................
program 5
..................
#include< stdio.h>
/* 配列を使う1 */
main()
{
float y[10]; 要素数10の配列yを宣言(要素の番号は0から9)
int i;
/* 配列データを作る */
for( i=0; i< 10; ++i){ {から}までをiの値0から9まで繰り返す
y[i] = 2.0 * i; 配列yの第i要素であるy[i]に値をいれる
}
/* 奇数番目のデータを出力 */
for( i=0; i< 9; i += 2){ iは0から8までの偶数をとる(++iではなくi+=2であることに注意。
また要素番号が0からなので、奇数番目のデータの要素番号は偶数である。
ややこしいがしょうがない)
printf("%f\n",y[i]); 配列yの第i要素y[i]を出力
}
/* 偶数番目のデータを出力 */
for( i=1; i< 10; i += 2){ iは1から9までの奇数(偶数番目のデータの要素番号は奇数である)
printf("%f\n",y[i]);
}
}
..................
program 6
..................
#include< stdio.h>
/* データを読んで平均と分散を計算するプログラム2(配列の利用) */
main()
{
float y[50]; 要素数50個の実数配列を宣言
float av,var,sum,sum2;
int n,i;
/* 配列にデータを読んでしまう */
scanf("%d",&n); データ数を変数nに読む
for( i=0; i< n; ++i){
scanf("%f",&y[i]); 配列yの第i要素y[i]にデータを読む
}
/* 配列にあるデータを使って計算 */
sum=0;
sum2=0;
for( i=0; i< n; ++i){
sum += y[i]; y[i]の値を変数sumに足す
sum2 += y[i]*y[i]; y[i]*y[i](y[i]の2乗)を変数sum2に足す
}
av = sum/n;
sum2 /= n;
var = sum2-av*av;
printf("number of data= %d\n",n);
printf("average= %f\n",av);
printf("variance= %f\n",var);
/* データの値とその平均値からのずれを出力 */
for( i=0; i< n; ++i){
printf("%d %f %f\n",i,y[i],y[i]-av); 番号iとデータy[i]および平均値との差y[i]-avを一行に出力
}
}
発展:
- 2次元データ(例えばx,yの組)を順に読んでそれぞれの平均を計算できるようにしてみる。
FORTRAN版
program 4
..................
C データを読んで平均と分散を計算するプログラム1
program main
C 変数の初期化
sum=0
sum2=0
C データを読みつつ、和を計算
read(*,*)n 整数変数nに標準入力から値を読む(読み込むデータの数)
(*,*)はおまじない
do i=1,n enddoまでをn回くりかえす(n個のデータをよんで処理)
read(*,*)y 実数変数yに標準入力から値を読む
sum = sum+y yの値を変数sumに足す
sum2 = sum+y**2 y**2(yの2乗)を変数sum2に足す
enddo
av = sum/n sum/nを変数avにいれる(データの平均値)
sum2 = sum2/n sum2をnで割る(データの2乗の平均値)
var = sum2-av**2 分散を計算して変数varに入れる
C 出力
write(*,*)"number of data= ",n データ数nを出力
write(*,*)"average= ",av 平均値avを出力
write(*,*)"variance= ",var 平均値avを出力
end
..................
program 5
..................
C 配列を使う1
program main
real y(10) 要素数10の配列yを宣言
C 配列データを作る
do i=1,10 enddoまでを配列の全要素(10個)について繰り返す
y(i) = 2.0 * i 配列yのi番目の要素y(i)に値をいれる
enddo
C 奇数番目のデータを出力
do i=1,10,2 iは1から10までの奇数をとる(iの値は2ずつ増える)
write(*,*)y(i) 配列yのi番目の要素y(i)を出力
enddo
C 偶数番目のデータを出力
do i=2,10,2 iは1から10までの偶数
write(*,*)y(i)
enddo
end
..................
program 6
..................
C データを読んで平均と分散を計算するプログラム2(配列の利用)
program main
real y(50) 要素数50の実数配列を宣言。扱えるデータ数の上限を50個に設定
C 配列にデータを読んでしまう
read(*,*)n データ数を変数nに読む
do i=1,n
read(*,*)y(i) 配列yのi番目の要素y(i)にデータを読む
enddo
C 配列にあるデータを使って計算
sum=0
sum2=0
do i=1,n
sum = sum+y(i) y(i)の値を変数sumに足す
sum2 = sum2+y(i)**2 y(i)**2(y(i)の2乗)を変数sum2に足す
enddo
av = sum/n
sum2 = sum2/n
var = sum2-av**2
write(*,*)"number of data= ",n
write(*,*)"average= ",av
write(*,*)"variance= ",var
C データの値とその平均値からのずれを出力
do i=1,n
write(*,*)i,y[i],y[i]-av 番号iとデータy(i)および平均値との差y(i)z-avを一行に出力
enddo
end
発展についてはC版と同様