課題 [13] 構造体(4/8)

問 4(提出プログラム名:ex1304a.h)

まず,このプログラム(ex1304a.c)とヘッダ(ex1304a.h)をそれぞれダウンロードしなさい.
そして,ex1304a.h (.hの方であり,.c ではない)を編集して次の処理を行うプログラムとして仕上げなさい.
※ヘッダの中で構造体の宣言が
  #ifndef __STRUCT_CITY
  #define __STRUCT_CITY

と
  #endif
で囲まれているが,これについては問 6 で使用するための措置なのでひとまず気にしなくてよい.

  
【目的の処理】
このプログラムでは 1 つの市の名前と人口を格納する CITY という構造体を定義している.
構造体 CITY のメンバは
  ■ name : その市の名前を格納する char 配列(内容の例:Matsuyama)
  ■ population:その市の人口を格納する int 変数(内容の例:511192 ← 松山市の人口)
となっている.

main 関数では愛媛県内の COUNT 個の市(COUNT はマクロとして定義してある)について,それぞれの市の名前と人口が書かれたデータファイルから内容を読み込み,CITY データの配列 cdata[] に格納している.
そして,関数 sort_p を呼び出し,その配列を人口の降順に(多い順に)並べ替えた後,データを画面に出力させようとしている.

関数 sort_p を完成させ,ex1304a.h のみを提出しなさい.
なお,並べ替えのアルゴリズムには以下に示すバブルソートを使用しなさい.

【ヒント】
最初にデータファイルから読み込んだ状態では
 cdata[0] が四国中央市のデータ
  (cdata[0].name が "Shikokuchuo" で cdata[0].population が 82754)
 になっていて,
 cdata[1] が新居浜市のデータ
  (cdata[1].name が "Niihama" で cdata[1].population が 115938)
 になっています.
 cdata[2] 以降も同様です.

バブルソートのアルゴリズムで降順に並べ替える場合,
例えば cdata[j] と cdata[j+1] の間で人口の大小関係を比較することになりますが,
この場合は if ( cdata[j] < cdata[j+1] ) と書くことはできません.
なぜなら cdata[j] や cdata[j+1] は構造体データであって直接数値を表しているわけではないからです.
それゆえ,人口を表す population に注目して
  if ( cdata[j].population < cdata[j+1].population )
といった比較が必要であることに注意してください.

なお,変数の入れ替えについては,CITY 型の変数(例えば tmp)を用意しておけば,
tmp = cdata[j]; だけで構造体データの内容をまとめてコピーできます.
つまり,通常の int 変数の場合の値の入れ替えと同じ書き方で大丈夫です.

【バブルソートのアルゴリズム】
例年,「ソーティング操作はできているがバブルソートとは違う」という解答が見られますので念の為に補足しておきます.
バブルソートは,a という配列に n 個のデータが格納されていた場合,隣どうしを比較・交換するという操作をひたすら繰り返すというものですので,例えば以下のようにして降順の並べ替えを実装できます:
  for ( i = 0; i < n-1; i++ )
  {
    for ( j = 0; j < n-1-i; j++ )
    {
      if ( a[j] < a[j+1] )
      {
        a[j] と a[j+1] を交換
      }
    }
  }

なお,上の例では a[j] と a[j+1] を直接比較していますが,この課題の場合は市の名前と人口の 2 種類のデータが a[j] や a[j+1] には入っているので,人口を使う場合は a[j].population や a[j+1].population となることに注意してください.

  • 【プログラムの実行結果】(その1)※赤字は実行時にキーボードから入力する内容
    (このデータファイル data1304a.txt をダウンロードして使ってください)
愛媛県内の市の人口データファイル名を入力してください⏎
> data1304a.txt
⏎
人口の降順に並べ替えると:⏎
 1) Matsuyama⏎
     (511192人)⏎
 2) Imabari⏎
     (151672人)⏎
 3) Niihama⏎
     (115938人)⏎
 4) Saijo⏎
     (104791人)⏎
 5) Shikokuchuo⏎
     ( 82754人)⏎
 6) Uwajima⏎
     ( 70809人)⏎
 7) Ozu⏎
     ( 40575人)⏎
 8) Seiyo⏎
     ( 35388人)⏎
 9) Iyo⏎
     ( 35133人)⏎
10) Toon⏎
     ( 33903人)⏎
11) Yawatahama⏎
     ( 31987人)⏎

【過去にあったミス(実際に減点となり,やり直しを命じられた例)】
■ 実行の画面出力の内容が上の例と違う(きちんと確認していない).
■ インデントに不備がある(VSCode 上でインデントを自動で揃える作業をやっていない).


ミスが無いことを確認したら次の問題へ → [ 問 5 (ex1305a.h) ]