C言語 偏差値を求める問題
0-10点の間でランダムに点数を発生させて平均値、最高値、標準偏差を求め、点数をソートして表示させるプログラムをc言語で作っています。
エラーメッセージは出ていないのですが、偏差値を正しく出力できません。
原因を教えていただきたいです。よろしくお願いします。
発生している問題・エラーメッセージ
3点 4点 10点 の偏差値がほぼ等しくなってしまうなど、正しく表示することができません。
実行結果 score,standard score 2 32.679492 3 55.772837 4 55.772879 10 55.774792 max: 10 ave: 4.750000
該当のソースコード
偏差値を求める関数 calc_deviation_score()
c
1 2#include <stdio.h> 3#include <stdlib.h> 4#include <time.h> 5#include <math.h> 6 7void set_array_rand(int n, int* score); 8int find_max_in_array(int n, int* score); 9double calc_ave(int n, int* score); 10int calc_sum(int n, int* score); 11void swap(int *a, int *b); 12void bubble_sort(int n, int *score); 13void print_array(int n, int* a); 14double calc_deviation_score(int n, int* score, int ten); 15 16#define N 4 17 18int main(void) 19{ 20 int i, id, max ; 21 int score[N]; 22 double ave; 23 24 printf("score,standard score \n"); 25 26 27 set_array_rand(N, score); 28 bubble_sort(N, score); /* sort here */ 29 print_array(N, score); 30 31 32 id = find_max_in_array(N, score); 33 max = score[id]; 34 ave = calc_ave(N, score); 35 printf("max: %d \n", max); 36 printf("ave: %f \n", ave); 37 38} 39 40 41/*random score */ 42void set_array_rand(int n, int* score) 43{ 44 int i; 45 srand((unsigned int)time(NULL)); 46 for (i = 0; i < n; i++) 47 { 48 score[i] = rand() % 11; 49 } 50} 51 52/* deviation_score */ 53double calc_deviation_score(int n, int* score, int ten) 54{ 55 int i; 56 double hensa; 57 double hensa2_array[N]; 58 double hensati; 59 60 double hensa2_ave; 61 double hensa2_sum = 0; 62 63 64 for (i = 0; i < n; i++) 65 { 66 hensa = score[i] - calc_ave(N, score); 67 hensa2_array[i] = hensa * hensa; 68 } 69 70 71 for(i = 0; i <= n-1 ; i++){ 72 hensa2_sum = hensa2_sum + hensa2_array[i]; 73 } 74 hensa2_ave = (double)hensa2_sum / n; 75 76 77 hensati = (( ten - calc_ave(N, score) ) / sqrt(hensa2_ave)) * 10 + 50; 78 79 return hensati; 80} 81 82 83 84/* print_array */ 85void print_array(int n, int* a) 86{ 87 int i; 88 int score[N]; 89 for (i = 0; i < n; i++){ 90 printf("%d ", a[i]); 91 printf("%f", calc_deviation_score(N, score, score[i])); 92 printf("\n"); 93 } 94 95} 96 97 98/* max */ 99int find_max_in_array(int n, int* score) 100{ 101 int id = 0; 102 int max = score[0]; 103 int i; 104 for (i = 1; i < n ; i++) { 105 if (score[i] > max ) { 106 id =i ; 107 max = score[id]; 108 } 109 } 110 return id; 111} 112 113 114 115/* average */ 116double calc_ave(int n, int* score) 117{ 118 int i; 119 int sum_score = 0; 120 double ave_score; 121 122 for(i = 0; i <= n-1 ; i++){ 123 sum_score = sum_score + score[i]; 124 } 125 ave_score = (double)sum_score / n; 126 return ave_score; 127} 128 129 130/* swap */ 131void swap(int *a, int *b) 132{ 133 int c; 134 c = *b; 135 *b = *a; 136 *a = c; 137} 138 139 140/* sort */ 141void bubble_sort(int n, int *score) 142{ 143 int i, j; 144 for (i = n-1; i > 0; i-- ){ 145 for (j = 0; j < i; j++ ){ 146 if (score[j] > score[j+1]) 147 swap(&score[j] , &score[j+1]); 148 } 149 } 150} 151
試したこと
点数の配列をランダムではなく自分で指定する方法のプログラムを作ったところ正しい偏差値が表示されたので、偏差値を求める関数calc_deviation_score() とその中で呼び出す関数 calc_ave() の式自体には問題はないかと思われます。
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#define N 5 5 6double calc_deviation_score(int n, int* score, int ten); 7double calc_ave(int n, int* score); 8 9 10int main(void) 11{ 12 int i; 13 int score[5]; 14 15 score[0] = 1; 16 score[1] = 4; 17 score[2] = 5; 18 score[3] = 8; 19 score[4] = 8; 20 21 for (i = 0; i < 5; i++){ 22 printf("%d ", score[i]); 23 printf("%f", calc_deviation_score(N, score, score[i])); 24 printf("\n"); 25 } 26 27 return 0; 28} 29 30 31 32/* deviation_score */ 33double calc_deviation_score(int n, int* score, int ten) 34{ 35 int i; 36 double hensa; 37 double hensa2_array[N]; 38 double hensati; 39 40 double hensa2_ave; 41 double hensa2_sum = 0; 42 43 44 for (i = 0; i < n; i++) 45 { 46 hensa = score[i] - calc_ave(N, score); 47 hensa2_array[i] = hensa * hensa; 48 } 49 50 51 for(i = 0; i <= n-1 ; i++){ 52 hensa2_sum = hensa2_sum + hensa2_array[i]; 53 } 54 hensa2_ave = (double)hensa2_sum / n; 55 56 57 hensati = (( ten - calc_ave(N, score) ) / sqrt(hensa2_ave)) * 10 + 50; 58 59 return hensati; 60} 61 62 63/* average */ 64double calc_ave(int n, int* score) 65{ 66 int i; 67 int sum_score = 0; 68 double ave_score; 69 70 for(i = 0; i <= n-1 ; i++){ 71 sum_score = sum_score + score[i]; 72 } 73 ave_score = (double)sum_score / n; 74 return ave_score; 75} 76 77
実行結果は以下の通りです。
(点数 標準偏差 の順に表示しています。)
1 34.079941 4 45.451412 5 49.241902 8 60.613373 8 60.613373
同様にscore[1]=8 score[3]=4 などscoreの順番を入れ替えて宣言してからバブルソートの関数をかませても同様の結果が得られました。
点数をランダムで作るアルゴリズムが原因でおかしくなってしまったのでしょうか。
補足情報
はじめは[点数][偏差値]の二次元配列を作ることを考えたのですが、まだ授業でポインタについて詳しくやっておらずほかの関数で呼び出す方法が難しそうだったため上のようなやり方で行いました。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/18 15:28
2018/12/19 09:52
2018/12/19 16:14