無題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
初心者

無題

#1

投稿記事 by 初心者 » 16年前

n人の学生の名前と英語,国語,数学の点数を読み込み,各人の3科
目の合計点,また各教科の平均点と標準偏差を計算して出力するプログラムを
作れという問題で下記のように作りました。
linuxとgccをつかってます。

実行できるのですがもっとコンパクトなプログラムにできないでしょうか?
最近関数を習ったのでそれを使うのではないかとおもうのですがよくわから
ないので教えてもらえるとありがたいです。

forの部分とかまとめられますか?

#include<stdio.h>
#include<math.h>
#define N 50

main()
{
int eng[N], jap[N], math[N], sum, n=0, i;
char name[N][12];
double SUM, sum1, sum2, sum3, ave1, ave2, ave3, vari, s_devi;


while(scanf("%s %d %d %d",&name[n][0],&eng[n],&jap[n],&math[n]) != EOF)
{
sum=0;
sum = eng[n]+jap[n]+math[n];
sum1 += eng[n];
sum2 += jap[n];
sum3 += math[n];
printf("name , sum : %-12s %4d\n",name[n], sum);
n++ ;
}

ave1 = sum1/n;
ave2 = sum2/n;
ave3 = sum3/n;

for(SUM=0,i=0; i<n; i++)
{
SUM += (eng-ave1)*(eng-ave1);
}
vari = SUM/n;
s_devi = sqrt(vari);
printf("English\naverage = %.2f\nstandard deviation = %.2f\n\n",ave1,s_devi);

for(SUM=0,i=0; i<n; i++)
{
SUM += (jap-ave2)*(jap-ave2);
}
vari = SUM/n;
s_devi = sqrt(vari);
printf("japanese\naverage = %.2f\nstandard deviation = %.2f\n\n",ave2,s_devi);

for(SUM=0,i=0; i<n; i++)
{
SUM += (math-ave3)*(math-ave3);
}
vari = SUM/n;
s_devi = sqrt(vari);
printf("math\naverage = %.2f\nstandard deviation = %.2f\n\n",ave3,s_devi);
}

ムンバ

Re:無題

#2

投稿記事 by ムンバ » 16年前

こんばんは。お世話になります。
ちょっと気になったので、横レスごめんなさい。(謝

n人の学生の名前と英語,国語,数学の点数を読み込み,各人の3科
目の合計点,また各教科の平均点と標準偏差を計算して出力するプログラムを
作れ

何となく検索してみたのですが

http://oshiete1.goo.ne.jp/qa4466285.html
http://qanda.rakuten.ne.jp/qa4466285.html
http://okwave.jp/qa4466285.html
http://oshiete.hito2.jp/qa4466285.html
http://soudan1.biglobe.ne.jp/qa4466285.html
http://qa.mapion.co.jp/qa4466285.html
(その他)

で、引っかかりました。
相変わらず変な意味は無いのですが、何でこれで検索にかかるのでしょうか?

初心者さん、ごめんなさい。
すごく気になったので、すみません。

ムンバ

Re:無題

#3

投稿記事 by ムンバ » 16年前

ちなみに

n人の学生の名前と英語,国語,数学の点数を読み込み,各人の3科
目の合計点,また各教科の平均点と標準偏差を計算して出力するプログラムを
作れという問題で下記のように作りました。
linuxとgccをつかってます。

で検索しても、上記と同じ様な結果(1件マイナス)が出ました。<by yahoo

どうしてなんでしょうか?^^;

Dixq (管理人)

Re:無題

#4

投稿記事 by Dixq (管理人) » 16年前

まず投稿前に規約をお読みになり、コードはタグを使い、トピには題名をつけて下さいね。

コードは変数名が重複している部分が多いですね。
ある変数をセットで使うなら構造体が便利です。
もし構造体についてご存じなければググって下さい。

コードはなるべく変えないように修正しました。
sum0, sum1, sum2は配列にして3回ループにすればさらに省けますね。


#include<stdio.h> 
#include<string.h> 
#include<math.h> 

/* 登録人数最大数 */
#define N 50

/* 生徒のスコアデータ */
typedef struct{
    int        SubScore[3];    //教科別スコア
    char    Name[64];        //名前
    double    Average;        //平均
}StudentData_t;

/* 教科別スコアデータ */
typedef struct{
    char    Name[12];        //教科名
    double    Average;        //平均
    double    StdDev;            //標準偏差
}SubScoreData_t;

int main(){
    int n=0, i , s; 
    int sum;
    double sum0, sum1, sum2;
    double Val, SubSum;
    StudentData_t    StudentData[N]    ={0,};
    SubScoreData_t    SubScoreData[3]    ={0,};

	/* 名前代入 */
    strcpy(SubScoreData[0].Name, "English");
    strcpy(SubScoreData[1].Name, "Japanese");
    strcpy(SubScoreData[2].Name, "Math");

	/* 初期化 */
    sum0 = sum1 = sum2 = 0;

	/* 代入しながらループ */
    while( scanf("%s %d %d %d", 
        StudentData[n].Name, 
        &StudentData[n].SubScore[0], 
        &StudentData[n].SubScore[1], 
        &StudentData[n].SubScore[2]    ) != EOF )
    {
		/* 3教科の合計 */
        sum = StudentData[n].SubScore[0] + StudentData[n].SubScore[1] + StudentData[n].SubScore[2];
		/* 各教科のスコアの加算 */
        sum0 += StudentData[n].SubScore[0]; 
        sum1 += StudentData[n].SubScore[1]; 
        sum2 += StudentData[n].SubScore[2]; 

        printf("name , sum : %-12s %4d\n", StudentData[n].Name, sum); 
        n++ ; 
    } 

	/* 平均の計算 */
    SubScoreData[0].Average = sum0 / n; 
    SubScoreData[1].Average = sum1 / n; 
    SubScoreData[2].Average = sum2 / n; 

	/* 3教科分ループ */
    for(s=0; s<3; s++)
    {
		/* 人数分ループ */
        for(SubSum=0,i=0; i<n; i++) 
        { 
            SubSum += (StudentData.SubScore - SubScoreData.Average)
                      * (StudentData.SubScore - SubScoreData.Average) ; 
        } 
        Val = SubSum / n ; 
        SubScoreData.StdDev = sqrt(Val); 
        printf("%s\naverage = %.2f\nstandard deviation = %.2f\n\n",
        SubScoreData.Name, SubScoreData.Average, SubScoreData.StdDev); 
    }

    return 0;
}
 
 

Dixq (管理人)

Re:無題

#5

投稿記事 by Dixq (管理人) » 16年前

>ムンバさん

以前そのURLにその類の質問があったのでしょう。
その後規約違反か何かで削除されたのでしょう。
タイムラグで検索データベースに残ってただけじゃないでしょうか。

ムンバ

Re:無題

#6

投稿記事 by ムンバ » 16年前

おはようございます。
そういう事でしたか。すみません、余計な事を。^^;
質問があったのですが、もう少し考えてみます。w
また、宜しくお願いします。

初心者

すみません

#7

投稿記事 by 初心者 » 16年前

構造体について調べてよくわからなかったので
大学の先生に質問したら構造体というのは使わないで作れといわれました。

プログラムを見せたら、
もっとまとめられるといわれましたが詳しく教えてくれませんでした。
構造体を使わないでまとめられませんか?

Mist

Re:すみません

#8

投稿記事 by Mist » 16年前

ん~、こういうことかな。

eng[N], jap[N], math[N]



seiseki[3][N]

とする。
seiseki[0] 英語
seiseki[1] 国語
seiseki[2] 数学

これでプログラム後半の標準偏差のところを
int kyouka;

for (kyouka = 0; kyouka < 3; kyouka++) {
    // 標準偏差の計算を行う
}
とすればかなり短くなると思います。

non

Re:すみません

#9

投稿記事 by non » 16年前

もしくは、点数の配列はそのままで、
標準偏差を計算する関数を作って、3回呼び出すのかも。
同じような処理が3回ですからね。

御津凪

Re:すみません

#10

投稿記事 by 御津凪 » 16年前

> 最近関数を習ったので

とありましたので関数にまとめたものを作ってみました。
void show_ave_sdiv( const int* points, int n, const char* coursename ){
    double ave, pt, ssum, sdiv;
    int i,sum;

    for(i = 0;i < n;++i){
        sum += points;
    }

    ave = sum / (double)n;

    for(i = 0,ssum = 0;i < n;++i){
        pt = points - ave;
        ssum += pt*pt;
    }

    sdiv = sqrt(ssum / n);

    printf("%s\naverage = %.2f\nstandard deviation = %.2f\n\n",coursename,ave,sdiv);
}

教科の各点数の配列、人数、教科名を引数とし、
その教科の平均点と標準偏差を計算、出力する関数です。

コンパイルチェックはしていませんので注意。

# 利用する場合はちゃんと理解してからじゃないと、先生に聞かれたときが大変です。

Dixq (管理人)

Re:すみません

#11

投稿記事 by Dixq (管理人) » 16年前

う~ん、授業以上のことを知ってるならそれで作ってもいいと思いますが・・。
こうなるとポインタ使うなconst使うなとか言われそうですね。
とりあえず上にも書いたとおり、
同じような変数が3つあるので配列にしてループさせるだけでいいと思いますよ。

バグ

Re:すみません

#12

投稿記事 by バグ » 16年前

試しに、なんでもかんでも関数化してみました(^_^;)
#include<stdio.h>
#include<math.h>
#define N 5

/* プロトタイプ宣言 */
int calcSum(int eng, int jap, int math);
double calcAvg(int* score, int count);
double calcStandardDeviation(int *score, int count);

/* メイン関数 */
int main() 
{
	char name[N][12];
	int eng[N], jap[N], math[N], i;

	for (i = 0; i < N; ++i)
	{
		/* 文字列の入力 */
		scanf("%s %d %d %d", name, &eng, &jap, &math);
		
		/* 入力データと合計値の表示 */
		printf("name , sum : %-12s %4d\n\n", name, calcSum(eng, jap, math));
	}

	/* 計算結果の表示 */
	printf("English\naverage = %.2f\nstandard deviation = %.2f\n\n", calcAvg(eng, i), calcStandardDeviation(eng, i));
	printf("Japanese\naverage = %.2f\nstandard deviation = %.2f\n\n", calcAvg(jap, i), calcStandardDeviation(jap, i));
	printf("Math\naverage = %.2f\nstandard deviation = %.2f\n\n", calcAvg(math, i), calcStandardDeviation(math, i));

	return 0;
} 

/* 3教科の合計値の計算 */
int calcSum(int eng, int jap, int math)
{
	return eng + jap + math;
}

/* 平均値の計算 */
double calcAvg(int* score, int count)
{
	int i, sum = 0;

	for (i = 0; i < count; ++i)
	{
		sum += *(score + i);
	}

	return (double)(sum) / (double)(count);
}

/* 標準偏差の計算 */
double calcStandardDeviation(int *score, int count)
{
	int i;
	double sum = 0.0, avg = calcAvg(score, count);

	for (i = 0; i < count; ++i)
	{
		sum += pow(*(score + i) - avg, 2.0);
	}

	return sqrt(sum / (double)count);
}

non

Re:すみません

#13

投稿記事 by non » 16年前

なるべく初心者さんがわかりやすいように変更をすくなくして、標準偏差だけを関数にしました。
double StandardDeviation(int n,int ten[/url],double ave)
{
	double sd=0;
	int i;
	for(i=0; i<n; i++) { 
		sd += (ten-ave)*(ten-ave); 
	} 
	sd = sqrt(sd/n);
	return sd;
}

関数呼び出しは
printf("English\naverage = %.2f\nstandard deviation = %.2f\n\n",ave1,StandardDeviation(n,eng,ave1));

バグ

Re:すみません

#14

投稿記事 by バグ » 16年前

よくよく見ると、私の投稿のcalcSum関数って、全く意味ないですね…(苦笑)

初心者

Re:

#15

投稿記事 by 初心者 » 16年前

皆さんありがとうございました^^
あとは自分でやってみようとおもいます。
またお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る