第 13 回 - ソーティング(2)

[6/16, 2006 H.Aman]
67x27(1669bytes)   67x27(1669bytes) 【課題 2】

例題 2

5 つの英文字を順に読み込み,配列 a に格納しなさい.
そして,それらをアルファベット順に並び替えて表示しなさい. ただし,使用する英文字は小文字に限定する.

方針・アルゴリズム

まず,長さ 5 の文字列を読み込み,配列 a へ格納する.
そして a[0], ..., a[4] をアルファベット順に並び替える.
前回 getchar の利用でも説明したように, 文字の実体は文字コード(整数)なので,文字どうしの大小比較は可能である. 実際,アルファベット順で先に登場するものほど小さい整数(文字コード)に対応する.
  • n = 4 〜 1 の範囲(-1 していく)で以下を繰り返す(右端をずらす):
    • m = 0 と仮定( a[0] の文字コードが最大と仮定 )する.
    • そして,i の値を 1 〜 4 の範囲で変化させながら, a[m] < a[i] ならば m ← i とする.
    • 最後に m < n なら a[m] と a[n] の値を交換する.
  • 並び替えた後の文字列を出力する.

コーディング例

     1	/*
     2	 * プログラミング演習 第 13 回
     3	 * [例題 2]
     4	 * (C) 2006 Hirohisa AMAN <aman@cs.ehime-u.ac.jp, aman@computer.org>
     5	 */
     6	#include <stdio.h>
     7	#include <string.h>
     8	
     9	int main(void){
    10	  char a[6], tmp;
    11	  int n, m, i;
    12	
    13	  /* 文字列を読み込む */
    14	  fgets(a, 6, stdin);
    15	  
    16	  for ( n = 4; n >= 0; n-- ){
    17	    m = 0;  /* a[0] 文字コードが最大と仮定 */
    18	    for ( i = 1; i <= n; i++ ){
    19	      if ( a[m] < a[i] ){ 
    20		m = i;  /* 最大値の位置の更新 */
    21	      }
    22	    }
    23	    if ( m < n ){ /* a[m] と a[n] の値を交換 */
    24	      tmp = a[m];
    25	      a[m] = a[n];
    26	      a[n] = tmp;
    27	    }
    28	  }
    29	  
    30	  printf("%s\n", a);
    31	
    32	  return 0;
    33	}
     
※左端の数字は行番号であり,ソースコードには含まれない点に注意!

コンパイル & 実行例

     $ gcc example13_2.c [Enter]
     $ ./a.out [Enter]
     stdio [Enter]
     diost
     

解説

上でも述べたように, 文字の実体は整数(文字コード) なので, 文字をアルファベット順に並べるという行為は 文字コードの小さい順に並べる という行為と同じである.
つまり,プログラムの内容は前回の 例題 2 とほとんど変らない.

並び替えの手順については前回の 例題 2 のページ を参考にしてもらうとして, ここではそれとの違いだけ述べる.

唯一の違いは,データの読み込みにある.
今回は文字列が対象データであるため,14 行目

     14	  fgets(a, 6, stdin);
にあるように, 文字列の読み込みを行う. その際,5 文字だけを読み込むので, 格納先の容量には 6 を指定する. なぜなら,文字列の終端を示す '\0' の分(1文字分)が追加で必要だからである.