C プログラミング (C Programming)

[2017/11/10, H.Aman]
[← 演習のページへ戻る]

サンプルプログラム 4 の内容

得点を SIZE 人分読み込み,それらを順に配列 a へ格納する.
その後に,それぞれの順位を求める.
最後に,1 番目の人から順に得点と順位を表示する.
なお,SIZE はマクロとして定義する.
 1:   #include <stdio.h>
 2:   
 3:   #define SIZE 5
 4:
 5:   int main(void){
 6:      int x[SIZE], rank[SIZE], i, j;
 7:      
 8:      printf("%d 人分の成績を入力してください:\n", SIZE);
 9:      for ( i = 0; i < SIZE; i++ ){
10:         scanf("%d", &x[i]);
11:      }   
12:      
13:      for ( i = 0; i < SIZE; i++ ){
14:         rank[i] = 1;
15:         for ( j = 0; j < SIZE; j++ ){
16:            if ( x[i] < x[j] ){ 
17:               rank[i]++;
18:            }
19:         }
20:      }
21:      
22:      for ( i = 0; i < SIZE; i++ ){
23:         printf("%d 番は %d 点で %d 位\n", i+1, x[i], rank[i]);
24:      }
25:
26:      return 0;
27:   }

プログラムの基本的な流れ

このプログラムでは,複数人分の得点を読み込み,それぞれの順位を求めています.
そのため,得点の記録用と順位の記録の 2 種類の配列を用意しています.
  • 配列 x : 各自の得点を記録
  • 配列 rank : 各自の順位を記録

プログラムの大まかな構成は次の通りです:
  1. 配列 x に 1 人ずつ得点を格納していく
  2. 1 人ずつ,その得点が「第何位」なのかを求めていく
  3. 最後に,得点と順位を出力する

8-11 行目: printf("...."); for ( i = 0; i < SIZE; i++ ){ ... }

 7:
 8:      printf("%d 人分の成績を入力してください:\n", SIZE);
 9:      for ( i = 0; i < SIZE; i++ ){
10:         scanf("%d", &x[i]);
11:      }   
12: 

for 文で繰り返しながら,SIZE 人分の得点を配列 x へ順に格納していきます.

13-20 行目: for ( i = 0; i < SIZE; i++ ){ rank[i] = 1; ... }

12:      
13:      for ( i = 0; i < SIZE; i++ ){
14:         rank[i] = 1;
15:         for ( j = 0; j < SIZE; j++ ){
16:            if ( x[i] < x[j] ){ 
17:               rank[i]++;
18:            }
19:         }
20:      }
21:

ここでは x[i] に格納されている得点順位rank[i] に格納することにします.

どうやったら順位を求めることができるのでしょう?ここがこのプログラムのポイントです.

このプログラムでは次の法則を利用して順位を求めています.
  • x[i] が 1 位である ⇔ x[i] よりも高い得点はない( 0 個)
  • x[i] が 2 位である ⇔ x[i] よりも高い得点が 1 個ある
  • x[i] が 3 位である ⇔ x[i] よりも高い得点が 2 個ある
  • ......
  • x[i] が k 位である ⇔ x[i] よりも高い得点が k-1 個ある
そこで次のように順位を決めています:
12:      
13:      for ( i = 0; i < SIZE; i++ ){
14:         rank[i] = 1; ← ひとまず x[i] の順位を 1 位としておく
15:         for ( j = 0; j < SIZE; j++ ){
16:            if ( x[i] < x[j] ){  ← x[i] よりも大きい値が見つかったら
17:               rank[i]++; ← x[i] の順位を一つ下げる(順位としては +1 する)
18:            }
19:         }
20:      }
21:
簡単な例として,配列 x の内容が次のようになっていたとします.
0 1 2 3 4
x 83 90 77 91 81

外側の for 文の 1 週目( i = 0)の時,まずは rank[i] = 1; つまり rank[0] = 1; とします.
0 1 2 3 4
rank 1 ? ? ? ?

続いて,内側の for 文で(SIZE=5のため) j = 0, 1, 2, 3, 4 と繰り返すと,
0 1 2 3 4
x 83 90 77 91 81

i

j

いきなり x[i] < x[j] に遭遇するため,rank[i]++; が実行されて
0 1 2 3 4
rank 2 ? ? ? ?

となります.その後
0 1 2 3 4
x 83 90 77 91 81

i

j
でも同じことが起こるので,再び rank[i]++ が行われ,
0 1 2 3 4
rank 3 ? ? ? ?

となります.
こうして,x[0] は 3 位であることが求まります.

次は,外側の for 文の 2 週目(i=1)について同様の処理が行われ,rank[1] が埋まっていきます.以下同様です.