成績の順位付けの課題です。

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

成績の順位付けの課題です。

#1

投稿記事 by hipsterswag » 8年前

平均値 (average) と標準偏差 (deviation) を表示し, キーボードから入力されたボーダーライン以上にいる学生のデータ(順位,学籍番 号,得点,偏差値)を下記のように表示されるプログラミングを作ってください。

Input a borderline (Score) (0<x<400): 380
average = 193.21, deviation = 123.99
1 | 76 | 394 | 66.19 |
2 | 78 | 391 | 65.95 |
3 | 20 | 389 | 65.79 |
4 | 52 | 387 | 65.63 |
5 | 21 | 385 | 65.47 |
6 | 3 | 383 | 65.31 |
7 | 5 | 380 | 65.07 |
rep_data2016.txtのデータ
1 303
2 362
3 383
4 208
5 380
6 271
7 40
8 344
9 19
10 319
11 48
12 139
13 94
14 146
15 221
16 65
17 126
18 261
19 60
20 389
21 385
22 270
23 376
24 347
25 352
26 24
27 226
28 212
29 272
30 135
31 294
32 54
33 137
34 246
35 20
36 151
37 22
38 18
39 46
40 42
41 240
42 276
43 47
44 227
45 41
46 256
47 169
48 16
49 100
50 168
51 239
52 387
53 280
54 282
55 299
56 301
57 167
58 244
59 30
60 317
61 210
62 51
63 235
64 333
65 175
66 89
67 59
68 35
69 361
70 8
71 76
72 97
73 98
74 357
75 159
76 394
77 375
78 391
79 155
80 369
81 273
82 44
83 351
84 360
85 73
86 75
87 365
88 115
89 194
90 106
91 70
92 3
93 228
94 156
95 25
96 108
97 355
98 173
99 250
100 77
下記のコードは私が作成したものです。

コード:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define Num 100

struct student{
    int num; //学籍番号//
    int score; //総点//
    double hensachi; //偏差値//
    double average; //平均//
    double deviation; //標準偏差//
};


void swap(struct student *x, struct student *y){
    struct student temp;
    
    temp = *x;
    *x   = *y;
    *y   = temp;
}


void readDataFile(struct student *Data){
    int i;
    int scannum;
    
    FILE *file=fopen("rep_data2016.txt","r");
    if(file ==NULL){
        fprintf(stderr,"cannot open file 'rep_data.txt'\n");
        exit(1);
    }
    
    for(i=0;i<Num; i++){
        scannum = fscanf(file,"%d%d%lf",&Data[i].num,&Data[i].score,&Data[i].hensachi);
        if (scannum !=4){
            fprintf(stderr,"cannot read file\n");
            exit(1);
        }
        
    fclose(file);
    
}

void QuickSortBase(struct student *Data, int left, int right){
    int pl,pr;
    double pivot;
    
    pl = left; pr =right;
    pivot = data[(pl+pr)/2].score;
    
    while(pl <= pr){
        while (data[pl].score > pivot) {
            pl++ ;
        }
        while (data[pr].score < pivot) {
            pr--;
        }
        if(pl<=pr){
            swap(&data[pl],&data[pr]);
            pl++;pr--;
        }
    }
    if(pl-left>=2){
        QuickSortBase( data, left, pr);
    }
    
    if(right-pr>=2){ 
        QuickSortBase( data, pl,right);
    }
    
}

void QuickSort(struct student *Data,int N) {
    if (N >= 2) {
        QuickSortBase(Data,0,N-1);
    }
//順位をつけるソートのコードが全然わからなくて本に書いてあったものを書きましたので合ってるかよくわかりません。//
    
}


int SerchScore(int score, struct student *Data,int N){
    struct student Result={0};
    int head=0,tail=N-1,mid;
    
    while(head<tail){
        
        mid=(head+tail)/2;
        if(sum >= Data[mid].score){
            tail =mid;
        }
        
        if(sum < Data[mid].score){
            head =mid+1;
        }
        
    }
    
    if(Data[head].score==score){
       	return Data[head];
    }else{
        printf("We don't have this student number:\n");
        return Result;
    }

    
    
}
// 総点を出すコード//


void CalcAveDev(struct student *Data){
   
    double sum(double data[], int n)
    {
        int i;
        double total = 0.0;
        
        for(i=1; i<=100; i++){
            total += data[i];
        }
        
        return total;          
    }

    double ave(struct student *Data, int n)
    {
        double total = sum(data, n);    
        return total/n;             	
    }
    double deviation(struct student *Data,int n)
    {
        
    }
    
}
//一番わからない部分です。標準偏差と偏差値、平均の公式の書き方がよくわかりません。//
    void writerank(struct student *Data){
        
        int i;
        for(i=0;i<Num;i++){
            Data[i].rank = i+1;
        }	
    }//順位をつけるコードです。//
int main(void){
    struct student Data[Num];
    int border, number;
    
    printf("Input a borderline (Score) (0<x<400):");
    scanf("%d",&border);
    
    readDataFile(Data);
    QuickSort(Data,Num);
    CalcAveDev(Data,Num);
    
    number = SerchScore(border,Data,Num);
    
    if(number <0||number>400){
        printf("Not Exist!\n");
    }else{
        PrintData(Data,number);
    }
    
    return 0;

}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 成績の順位付けの課題です。

#2

投稿記事 by みけCAT » 8年前

hipsterswag さんが書きました:平均値 (average) と標準偏差 (deviation) を表示し, キーボードから入力されたボーダーライン以上にいる学生のデータ(順位,学籍番 号,得点,偏差値)を下記のように表示されるプログラミングを作ってください。
課題の丸投げは禁止です。
フォーラムルールを読み、従ってください。
オフトピック
プログラムではなくプログラミングを作るというのは、どういうことなんだろう…?
hipsterswag さんが書きました:下記のコードは私が作成したものです。
このコードについて何か質問はありますか?

【追記】コード内のコメントとして質問が書いてあるのですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 成績の順位付けの課題です。

#3

投稿記事 by みけCAT » 8年前

hipsterswag さんが書きました:

コード:

struct student{
    int num; //学籍番号//
    int score; //総点//
    double hensachi; //偏差値//
    double average; //平均//
    double deviation; //標準偏差//
};
コメントでも文字列でもない場所に全角スペースがあるため、
コンパイラによってはコンパイルエラーになります。
hipsterswag さんが書きました:

コード:

void readDataFile(struct student *Data){
    int i;
    int scannum;
    
    FILE *file=fopen("rep_data2016.txt","r");
    if(file ==NULL){
        fprintf(stderr,"cannot open file 'rep_data.txt'\n");
        exit(1);
    }
    
    for(i=0;i<Num; i++){
        scannum = fscanf(file,"%d%d%lf",&Data[i].num,&Data[i].score,&Data[i].hensachi);
        if (scannum !=4){
            fprintf(stderr,"cannot read file\n");
            exit(1);
        }
        
    fclose(file);
    
}
fscanfで3個しかデータを読み込もうとしていないのに、4個読み込めなかったら終了という処理になっているのはおかしいと思います。
また、for文の{に対応する}が無いため、コンパイルエラーになるでしょう。
hipsterswag さんが書きました:

コード:

int SerchScore(int score, struct student *Data,int N){
    struct student Result={0};
    int head=0,tail=N-1,mid;
    
    while(head<tail){
        
        mid=(head+tail)/2;
        if(sum >= Data[mid].score){
            tail =mid;
        }
        
        if(sum < Data[mid].score){
            head =mid+1;
        }
        
    }
    
    if(Data[head].score==score){
       	return Data[head];
    }else{
        printf("We don't have this student number:\n");
        return Result;
    }

    
    
}
戻り値の型がintでは、struct student型のデータをreturnすることはできないでしょう。
hipsterswag さんが書きました:

コード:

// 総点を出すコード//


void CalcAveDev(struct student *Data){
   
    double sum(double data[], int n)
    {
        int i;
        double total = 0.0;
        
        for(i=1; i<=100; i++){
            total += data[i];
        }
        
        return total;          
    }

    double ave(struct student *Data, int n)
    {
        double total = sum(data, n);    
        return total/n;             	
    }
    double deviation(struct student *Data,int n)
    {
        
    }
    
}
関数内での関数の定義は標準規格にはなく、GCC拡張です。
必要がなければ使わないべきでしょう。

また、sum関数の実装が不自然です。
dataの最初の要素が足されない上、dataが100要素しかなければ範囲外アクセスが発生してしまいます。
100というマジックナンバーが使用されているのも良くないでしょう。
(readDataFile関数やwriterank関数では、ちゃんと0から処理を始め、Numまでになっていますよね?)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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