A問題(50点)
通常、平均値を求める場合は、全ての要素(数値)を足してから、その個数で除算する。しかし、前回までの平均値と新たな入力値から逐次その時点での平均値を求めることもできる。このような平均値の算出方法を逐次平均と呼び、プログラムの実行中にデータが次々と入力されるようなときに、入力毎逐次平均値を計算、表示させることもできる。
% ./a.out 入力データ: 2.0 データ数:1,平均:2.000000 入力データ: 4.0 データ数:2,平均:3.000000 入力データ: 6.0 データ数:3,平均:4.000000 入力データ: 8.0 データ数:4,平均:5.000000 入力データ: ^D 最終結果はデータ数4で、平均値5.000000でした % ./a.out 入力データ: 2.2 データ数:1,平均 = 2.200000 入力データ: 3.6 データ数:2,平均 = 2.900000 入力データ: 0.6 データ数:3,平均 = 2.133333 入力データ: 7.9 データ数:4,平均 = 3.575000 入力データ: 7.7 データ数:5,平均 = 4.400000 入力データ: 4.9 データ数:6,平均 = 4.483333 入力データ: ^D 最終結果はデータ数6で、平均値4.483333でした %
B問題(50点)
#include <stdio.h> #include <stdlib.h> #include <time.h> /* 乱数初期設定に必要 */ #define ROW 6 #define COL 10 int main() { int array[ROW][COL]; int n=0,data; int i,j; /* 必要に応じて変数宣言を追加 */ /* データ作成 */ srand((unsigned int)time(NULL)); /* 乱数初期設定 */ for (i=0; i<ROW; i++) { for (j=0; j<COL; j++) { array[i][j]=rand()%100; /* 0-99の乱数生成 */ } } printf("数値を入力して下さい:"); scanf("%d",&data); /* これ以降を作成 */ return 0; }
% ./a.out 数値を入力して下さい:5 8 27 59 90 11 33 1**68 23 81 50 52 63 73 57 63 6 57 26 75 9 70 11 94 71 4**92 35 2 5** 6 63 85 18 53 96 51 6 16 26 87 66 30 2 39 40 17 45 97 95 21 6 65 84 53 37 89 97 24 43 5以下の値は3個ありました % ./a.out 数値を入力して下さい:2 92 4 91 51 10 11 62 65 42 20 40 20 22 71 34 64 66 95 22 3 40 68 49 90 30 34 20 61 98 97 84 90 6 76 41 53 39 55 18 81 75 11 53 98 82 87 14 5 35 36 4 75 56 5 18 38 39 38 52 38 2以下の値はありませんでした %
会津大での評点(100点満点)と評価(A,B,C,D,F)は 以下のように対応している。
#define MAX_ST_NUM 50 /* 学生数の最大値 */ #define MAX_SCORE 120 /* 120点満点 */ int student_id[MAX_ST_NUM]; /* 学籍番号 */ int abs_score[MAX_ST_NUM]; /* 点数 (補正前) */ char abs_grade[MAX_ST_NUM]; /* 補正前の評価 (A - F) */ int rel_score[MAX_ST_NUM]; /* 点数 (補正後) */ char rel_grade[MAX_ST_NUM]; /* 補正後の評価 (A - F) */ int grade_dist[2][5]; /* 評価の分布 [0]:補正前, [1] 補正後 */ /* 例 grade_dist[0][0] 補正前の Fの人数 */ char cgrade[5]={'F','D','C','B','A'}; /* 評価(A - F) */ int num_student; /* 実際に成績を読み込んだ学生の数 */ double abs_ave=0.0; /* 平均点(補正前) */ double rel_ave=0.0; /* 平均点(補正後) */
main
関数および その他の関数のおおまかな構成と動作を以下に示す。int calib(int); /* 満点の補正を行う。内部では実数で計算し、小数点第1位で四捨五入した整数を返す */ int main() { /* 標準入力から学籍番号と点数を読みこむコードをここに書く。 */ adjust_score(); /* 点数を補正し、補正後の点数の配列に書きこむ。*/ /* 補正前・補正後の各学生の評価(A~F)を決定し、それぞれ 平均点と評価分布を求める*/ print_grade(); /* 補正前と後の点数と評価を表示。実行例参照 */ print_stat(); /* 統計と評価分布を表示。フォーマットは実行例参照 */ return 0; }
% ./a.out < score_data.txt ID 点数 評価 点数 評価 (補正前) (補正後) ------------------------- 10001 67 B 56 C 10002 120 A 100 A ... (略) 10016 64 C 53 C ------------------------- 統計 学生数 16人 補正前平均点 58.6点 補正後平均点 48.9点 評価分布 補正前 A 3 B 3 C 3 D 4 F 3 補正後 A 1 B 2 C 5 D 3 F 5 %
Extra問題
void grade_search(char)
を追加し、使用すること。
評価該当者一覧表示のためのキーボード入力は、繰り返し入力できるようにしておき、
EOF(Ctrl+D, ^D)が入力された場合、プログラムを終了するものとする(この時、評価指定の入力の後に打鍵するリターンは読み飛ばすようにしておく必要がある。この処理を入れないと、繰り返し入力時に支障が出る)。
% ./a.out (略) 評価分布 補正前 A 3 B 3 C 3 D 4 F 3 補正後 A 1 B 2 C 5 D 3 F 5 表示したい評価を大文字で入れてください(A-D,F): A Aの一覧 10002 100 A 表示したい評価を大文字で入れてください(A-D,F): C Cの一覧 10001 56 C 10005 53 C 10012 64 C 10015 59 C 10016 53 C 表示したい評価を大文字で入れてください(A-D,F): ^D %
#include <stdio.h> #define N 5 #define EMPTY -1 #define FULL -2 int stackIO(int); int main() { int n, r; printf("スタックを実現するプログラム\n"); printf(" 正の整数値:入力値をスタックに格納する(Push)\n"); printf(" 負の整数値:スタックからデータを取り出す(Pop)\n"); printf(" 0:終了\n"); while (1) { printf("整数値を入力 (正:格納(Push),負:取出(Pop),0:終了): "); scanf("%d", &n); if (n == 0) break; /* 終了 */ r = stackIO(n); /* 格納または取出 */ if (r > 0) printf("取出データ = %d\n", r); /* 取得データの表示 */ else if (r == EMPTY) printf("エラー(スタックが空です)\n"); else if (r == FULL ) printf("エラー(スタックが満杯です)\n"); stackIO(0); /* 表示 戻り値は使用しない */ } return 0; } /* [引数] 正の整数: 格納,負の整数: 取出,0: 表示 [戻り値] 格納の場合) スタックが満杯: マクロ定数 FULL,それ以外: 0 取出の場合) スタックが空: マクロ定数 EMPTY,それ以外: 取り出した値 表示の場合) 0 */ int stackIO(int x) { static int stack[N]; /* データを格納する配列 */ static int size = 0; /* データ数 */ /* ここを作成 */ }
% ./a.out スタックを実現するプログラム 正の整数値:入力値をスタックに格納する(Push) 負の整数値:スタックからデータを取り出す(Pop) 0:終了 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 31 size = 1 [31 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 41 size = 2 [31 41 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 59 size = 3 [31 41 59 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 59 size = 2 [31 41 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 26 size = 3 [31 41 26 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 53 size = 4 [31 41 26 53 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 58 size = 5 [31 41 26 53 58 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 58 size = 4 [31 41 26 53 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 53 size = 3 [31 41 26 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 26 size = 2 [31 41 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 97 size = 3 [31 41 97 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 97 size = 2 [31 41 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 41 size = 1 [31 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 31 size = 0 [] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 0 % ./a.out スタックを実現するプログラム 正の整数値:入力値をスタックに格納する(Push) 負の整数値:スタックからデータを取り出す(Pop) 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 1 size = 1 [1 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 2 size = 2 [1 2 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 3 size = 3 [1 2 3 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 4 size = 4 [1 2 3 4 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 5 size = 5 [1 2 3 4 5 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 6 エラー(スタックが満杯です) size = 5 [1 2 3 4 5 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 5 size = 4 [1 2 3 4 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 4 size = 3 [1 2 3 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 3 size = 2 [1 2 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 2 size = 1 [1 ] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 取出データ = 1 size = 0 [] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1 エラー(スタックが空です) size = 0 [] 数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 0 %
#include <stdio.h> #define N 5 #define EMPTY -1 #define FULL -2 int queueIO(int); int main() { int n, r; printf("キューを実現するプログラム\n"); printf(" 正の整数値:入力値をキューに格納する(Enqueue)\n"); printf(" 負の整数値:キューからデータを取り出す(Dequeue)\n"); printf(" 0:終了\n"); while (1) { printf("整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): "); scanf("%d", &n); if (n == 0) break; /* 終了 */ r = queueIO(n); /* 格納または取出 */ if (r > 0) printf("取出データ: %d\n", r); /* 取得データの表示 */ else if (r == EMPTY) printf("エラー(キューが空です)\n"); else if (r == FULL ) printf("エラー(キューが満杯です)\n"); queueIO(0); /* 表示 戻り値(0)は使用しない */ } return 0; } /* [引数] 正の整数: 格納,負の整数: 取出,0: 表示 [戻り値] 格納の場合) キューが満杯: マクロ定数 FULL,それ以外: 0 取出の場合) キューが空: マクロ定数 EMPTY,それ以外: 取り出した値 表示の場合) 0 */ int queueIO(int x) { static int queue[N]; /* データを格納する配列 */ static int head = 0, tail = 0, size = 0; /* 先頭,末尾,データ数 */ /* ここを作成 */ }
% ./a.out キューを実現するプログラム 正の整数値:入力値をキューに格納する(Enqueue) 負の整数値:キューからデータを取り出す(Dequeue) 0:終了 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 31 head = 0, tail = 1, size = 1 [31 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 41 head = 0, tail = 2, size = 2 [31 41 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 59 head = 0, tail = 3, size = 3 [31 41 59 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 31 head = 1, tail = 3, size = 2 [41 59 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 26 head = 1, tail = 4, size = 3 [41 59 26 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 53 head = 1, tail = 0, size = 4 [41 59 26 53 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 58 head = 1, tail = 1, size = 5 [41 59 26 53 58 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 41 head = 2, tail = 1, size = 4 [59 26 53 58 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 59 head = 3, tail = 1, size = 3 [26 53 58 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 26 head = 4, tail = 1, size = 2 [53 58 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 97 head = 4, tail = 2, size = 3 [53 58 97 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 53 head = 0, tail = 2, size = 2 [58 97 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 58 head = 1, tail = 2, size = 1 [97 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 97 head = 2, tail = 2, size = 0 [] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 0 % ./a.out キューを実現するプログラム 正の整数値:入力値をキューに格納する(Enqueue) 負の整数値:キューからデータを取り出す(Dequeue) 0:終了 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 1 head = 0, tail = 1, size = 1 [1 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 2 head = 0, tail = 2, size = 2 [1 2 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 3 head = 0, tail = 3, size = 3 [1 2 3 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 4 head = 0, tail = 4, size = 4 [1 2 3 4 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 5 head = 0, tail = 0, size = 5 [1 2 3 4 5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 6 エラー(キューが満杯です) head = 0, tail = 0, size = 5 [1 2 3 4 5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 1 head = 1, tail = 0, size = 4 [2 3 4 5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 2 head = 2, tail = 0, size = 3 [3 4 5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 3 head = 3, tail = 0, size = 2 [4 5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 4 head = 4, tail = 0, size = 1 [5 ] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 取出データ = 5 head = 0, tail = 0, size = 0 [] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1 エラー(キューが空です) head = 0, tail = 0, size = 0 [] 整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 0 %