• ベストアンサー

分散を求めるプログラム

n人の点数を読み込みそれらの平均、分散を計算するプログラムを作りたいのですが分散の式がよく分かりません。 分散を求める式は第i番目の点数をxi、平均をμとすると 分散=1/nΣxi^2-μ^2 で、プラグラムを作ってみると #include<stdio.h> int main (void) { int i; int sum=0; int num,tmp; printf("何人ですか"); scanf("%d",&num); for(i=0; i<num; i++) { print("No. %d ", i+1) scanf("%d",&tmp); sum += tmp; } printf("平均:%.3f\n",(double)sum/num); printf("分散:%.3f\n",(double){(sum-sum/num)*(sum+sum/num)}/num); return(0); } というプログラムを作ってみたのですが分散の計算がうまくいきません。どなたか分散の計算のプログラムを教えて下さい。 C言語初めてまもないので不備があったらすみません。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

こんばんわ。 ぱっとみでおかしいなと思った部分は、 Σxi^2の部分だと思います。 Σxi^2っていうのは、 Σxi^2=Σx1^2+Σx2^2+・・・+Σxnum^2 っていうことです。 dogtaisiさんはΣxi^2をsum^2と計算しているので 分散の計算がおかしくなっているんじゃないでしょうか? for文の中に、Σxi^2を計算する式を改めて作ってみるのはどうでしょう? for(i=0; i<num; i++) { print("No. %d ", i+1) scanf("%d",&tmp); sum += tmp; sigmax2 += tmp*tmp; } みたいな感じで。 自分自身も初心者なんで、的外れならごめんなさいね。

dogtaisi
質問者

お礼

回答有難うございました!

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

#1 の方へ 式を変形すると http://aoki2.si.gunma-u.ac.jp/lecture/Univariate/variance.html (1/nΣxi^2) - μ^2 になります(質問者さんにもわかりやすいように括弧をつけます)。 オーバーフローしやすいのであまり使いませんけど。 で、質問者さんのプログラムのおかしい点は#2さんの指摘の通りです。 各要素の2乗の和の平均を求めた上で、そこから平均値の2乗を引きます。

dogtaisi
質問者

お礼

回答有難うございました!

  • killer_7
  • ベストアンサー率57% (58/101)
回答No.1

分散は, 1/nΣxi^2-μ^2 でなく, 1/nΣ(xi-μ)^2 です.

参考URL:
http://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3

関連するQ&A

  • for文

    #include <stdio.h> int main(void) { int i; int sum=0; int num, tmp; printf("整数は何個かな:"); scanf("%d",&num); for(i=0; i<num; i++){ printf("No.%d:",i+1); scanf("%d",&tmp); sum+=tmp; } printf("合計値は:%d\n",sum); printf("平均値は:%.2f\n", (double)sum/num); return(0); } 上の文のforの箇所を for(i=1; i<=num; i++){ printf("No.%d:",i); scanf("%d",&tmp); sum+=tmp;   } としても結果的に同じですよね? どっちでもいいかどうか迷ってます。教えて下さい。

  • c言語 for文

    /*指定された個数だけ整数を読み込んで合計値・平均値を算出*/ #include <stdio.h> int main(void) { int i; int sum=0; int num,tmp; printf("整数は何個ですか:"); scanf("%d",&num); for(i=0;i<num;i++) {printf("No.%d:",++i); scanf("%d",&tmp); sum = sum + tmp; } printf("合計値:%d\n",sum); printf("平均値:%.2f\n",(double)sum / num); return(0); } C言語の勉強を始めたばかりのものです。 指定された個数だけ読み込めません 汗 前置と後置をまぜたあたりがよくないのかなと思うのですが。。。 どうしておかしくなるのか教えてください。 内部でどういった処理が行われているのかまだあまりわからない状態です。 ちなみに4と入力した結果は以下です。 整数は何個ですか:4 No.1:4 No.3:3 合計値:7 平均値:1.75

  • c言語で平均をだす

    #include<stdio.h> int main(void) { int num; int sum; printf("テストの点数を入力してください。\n"); do{ scanf("%d",&num); sum+=num; }while(num); printf("テストの合計点は%dです\n",sum); return 0; } テストの平均点をだすプログラムを作りたいのですが、合計を出すまではわかったのですが、ここから、平均を出すようにするにはどうすればよいですか。

  • C言語が分からないので分かる方説明お願いします

    C言語が分からないので分かる方説明お願いします #include<stdio.h> int main(void) { int i; int tensu[5]; int sum=0; printf(”点数を入力してください。”); for(i=0;i<5;i++){ printf(”%2d番:”,i+1); scanf(”%d”,&tensu[i]); sum+=tensu[i]; } printf(”合計点:%5d¥n”,sum); printf(”平均点:%5.1f¥n”,(double)sum/5); return(0); } 実行すると 点数を入力してください。 1番:95 2番:83 3番:85 4番:63 5番:89 合計点:415 平均点:83.0 できるだけ詳しく教えてください

  • C言語の添削

    「C言語基礎課題1」 #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <tchar.h> #include <ctype.h>                                       #include <string.h> #define MAX 100 /*点数*/ int flag; double avg(double t[],int n); int str_check(char s[]);                                        int main() { int number; //人数 double score[MAX]; //点数 char temp[MAX]; char str[MAX]; //名前 double ans; //平均成績 int i=0; //カウンタ変数 //人数の決める printf("人数を入力して下さい。\n"); scanf("%d",&number); //名前の入力 for(i=0;i<number;i++) { printf("%d番様の名前を入力して下さい。\n",i+1); scanf("%s",&str[i]); } //点数の入力 for(i=0;i<number;i++) { printf("%d番様の点数を入力して下さい。\n",i+1); scanf("%s",&temp); str_check(temp); if(flag==1) { score[i]=atoi(temp); //点数入力で有効範囲をチェック if(score[i]<0 || score[i]>100) { printf("0-100点の範囲を入力して下さい。\n"); i--; } } if(flag==0) { printf("点数を数字で入力して下さい。\n"); i--; } } ans =avg(score,number); printf("\n=====入力内容一覧と成績平均値======\n"); for(i=0;i<number;i++) { printf("%d番の点数は%3.2lfです。\n",i+1,score[i]); } printf("平均点は%3.2lfです。\n",ans); printf("=====================================\n"); getch(); return 0; } /*avg関数の定義*/ double avg(double t[],int n) { int i; double sum; sum = 0.0; for(i=0;i<n;i++) { sum += t[i]; } return sum/n; } /*点数入力で文字か数字かチェック*/ int str_check(char s[]) { int i=0,n; //カウンタ変数 n=strlen(s); while(s!='\0') { if(s[i]>='0'&&s[i]<='9'||s[i]=='.') { i++; } else { break; } } if(i==n) { flag=1; } else { flag=0; } return flag; } [最初に組んだソースプログラム] #include<stdio.h> #include<stdio.h> #define NUM 3 /*点数*/ #define Name 3 /*人数*/ #include<conio.h> double avg(int t[]); struct stList{ char str[Name][100]; int score[NUM]; int i,j; }; int main(void) { int score[NUM]; //char str[Name]; char str[100]; int i,j; double ans; printf("名前を入力して下さい。\n",Name); for(i=0;i<Name;i++){ scanf("%s",&str[Name]); } // if(score[NUM]=0 || score[NUM]<=100) //{ // printf("点数を入力して下さい。\n",NUM); //} printf("点数を入力して下さい。\n",NUM); for(i=0;i<NUM;i++) { scanf("%d",&score[i]); if(score[i]<0 || score[i]>100) { printf("0-100点の範囲を入力して下さい。\n"); i--; } } for(j=0;j<NUM;j++){ printf("%d番目の人の点数は%dです。\n",j+1,score[j]); } ans =avg(score); printf("平均点は%3.2lfです。\n",ans); getch(); return 0; } /* avg関数の定義 */ double avg(int t[]) { int i; double sum; sum = 0.0; for(i=0;i<3;i++){ sum += t[i]; } return sum/Name; } 「一人分のデータを保持する構造体(文字列と整数の変数をメンバに持つ)を用意し、3人分の名前と成績 (最大値100、最小値0)を入力でき、入力が終了したら、入力内容一覧と成績の平均値を表示する プログラムを作成せよ。 ※考えうる限りの異常系処理の導入、関数化を行うこと。」 研修で以下の指摘を受けました。 (1)compare関数が使われていない。 (2)名前入れる変数が3つ不明 (3)カウンタ変数がi,j,s,tになっている理由は? (4)名前を入力しなかった時の処理 (5)点数を処理しなかった時の処理 (6)定数NUMで人数3を指定できるようにしているのにプログラムはそれを利用仕切れていない(名前入力が固定3人)ので無意味 (7)if(tmp=0 || tmp<=100)←これなんでしょうか? (8)平均点表示の少数点以下有効桁数はどうなっているのか? (9)点数入力で文字を入れたときの処理 (10)点数入力で有効範囲外の数字を入れた時の処理 ちなみに最大値、最小値はdefineして欲しいです。理由は(2)に読めば分かる (11)変数名が謎なのが多い 課題のキーワードのどこにも出て来ないですし言葉だから 後、添付ファイルを添付します。 最初のソースプログラム名「最初に組んだもの」修正したものが「C言語基礎課題1」と名付けています。 いづれのソースプログラムも構造体を用意出来てないように思うのですがいかかですか?

  • ループ

    #include<stdio.h> int main(void) { int i=1,sum=0; int num=1; while(num>0) { printf("整数を入力してください。(マイナスの値で終了)\n"); scanf("%d",&num); printf("%dが入力されました。(%d番目の繰り返しです)\n",num,i); sum+=i; printf("1から%dまでをたすと%dです。\n",i,sum); i++; } printf("繰り返しが終わりました。\n"); printf("加算値は%dです。\n",sum); printf("%d回繰り返しました。\n",i); return 0; } このプログラムで101以上の数値は加算しないようにするにはどうすればいいですか。

  • 配列 平均値と分散値

    #include <stdio.h> void mean_vari(int *s, int n, double *mean, double *variance); int main(void) { int i, n; int a[]={34, 54, 21, 80, 60, 90, 15, 24, 100}; double heikin, bunsan; mean_vari(&i,n,&heikin,&bunsan); printf("平均=%f 分散=%f\n",heikin,bunsan); return (0); } /* 合計を求める関数 */ void mean_vari(int *s, int n, double *mean, double *variance) { int i; int sum=0; /* 合計の初期化 */ double sum2=0; for (i = 0; i < n; i++) sum += s[i]; ????=sum/(double)????; for (i = 0; i < n; i++){ sum2 +=????; } ????=????; } 平均値と分散値を求めたいのですが、????の部分になりをいれていいかわかりません。 教えてください。

  • C言語のプログラム添削お願いします

    #include<stdio.h> int main(void) { int a[4]; int i=0; int n; int sum=0; printf("正数を入力してください\n"); while(i<=4) {scanf("%d",&n); if(n>=0) {a[i]=n; sum=sum+a[i]; i++; } else{printf("正数を入力してください");} } printf("正数の合計値は%dです",sum); printf("正数の平均値は%lfです",(double)(sum/5)); return(0); } 上記は正数のみ配列に保存し、その合計と平均を表示するプログラムを 製作しようとして書いたものですが次のような問題点があり正常に機能しません。 (1)a[i]=n;をn=a[i];と置き換えると不正な値が表示される (2)平均値の小数点以下の値がおかしい   (例)8+8+8+9+8と入力し合計値41に対し、平均値が8.000000 解決法が分からず困っています。どなたかお力添えお願いします。

  • C言語初心者です。次のプログラムを簡潔にしたいです

    二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成せよ。 自分のプログラムは以下の通りです。 #include <stdio.h> int main(void) { int num1,num2,small,big,sum=0; printf("二つの整数を入力してください。\n"); printf("整数A:"); scanf("%d",&num1); printf("整数B:"); scanf("%d",&num2); small=(num1 > num2) ? num2 : num1; big=(num1 > num2) ? num1 : num2; printf("%d以上%d以下の全整数の和は",small,big); if (num1 < num2) { do { sum+=num1; num1++; }while (num1 <= num2); } else { do { sum+=num2; num2++; }while (num2 <= num1); } printf("%dです。",sum); return 0; } 結果は正しく表示されるはずです。 しかし多変数かつループ文を組み合わせているため、長ったらしくなっています。 どのようなプログラミングならば、簡潔にかけますか? 解答がないので困っています。

  • 標準偏差・分散

    標準偏差と分散を求めるプログラムで #include <stdio.h> #include <math.h> int main(void){ int i; double data[10]; double heikin, total = 0.0, variance = 0.0, deviation = 0.0; for ( i = 0; i < 10; i++ ){ printf("%d番目の値を入力:",i + 1); scanf( "%lf",&data[i] ); total += data[i]; } heikin = total / 10.0; for(i = 0; i < 10; i++ ){ variance += ((data[i]-heikin)*(data[i] - heikin))/10.0; } deviation += sqrt(variance); printf("平均値は%f\n" , heikin ); printf("分散は%fです。\n",variance); printf("標準偏差は%fです\n",deviation); getchar(); getchar(); return(0); } という感じでいいのでしょうか? 分散と標準偏差の式はこれであっているとおもうのですが・・・・。

専門家に質問してみよう