Top / AProg / 2016 / ex06

応用プログラミング及び実習 2016年度 第6回 [edit]

注意 [edit]

  • 実習のすすめ方について AProg/2016/ex00
  • Linux環境での操作についてわからないことがあったら Docs/4UNIXBeginners
  • 締切に間に合わずチェックを受けられなかった課題は自分で完成させておくこと. 先の回には,過去の課題のプログラムを改造して新たなプログラムを作る課題があります. 締切後には点数はつきませんが,質問等は随時どうぞ.

課題A(self) 締切:1講時終了時 [edit]

構造体の学習(2)

講義資料の構造体配列を使うプログラムの例を実際に作って動かそう.

  • kcard.h および kcard.c は,前回の課題B のものを修正すればよい
  • kenshin4.c は講義資料の通り作ろう
  • data.txt は講義資料のものを参考に自分で適当に作ったらよい

課題B(TA) 締切: 今回の実習終了20分前 [edit]

郵便番号データを読み込むプログラムを作ろう

12万件以上の郵便番号データを収めたファイルが

/roes/sample/takataka/aprog20XY/zipdata

という名前で置いてある(XYは...).このファイルには,次のような形式で郵便番号と住所が書かれている.

6148062 京都府八幡市八幡清水井
3500263 埼玉県坂戸市堀込
   :

これを読み込んで一部の内容を表示するプログラムを作ろう.ただし,ソースファイルは次の2つから成るものとする.

ex06zip.h
郵便番号簿データ(郵便番号と住所)を格納するための構造体(詳しくは後述)の定義を書いたヘッダファイル
ex06b.c
main関数を定義したソースファイル.

以下の注意をよく読んで作成すること.

check 構造体の定義に関する注意

  • 定義する構造体は,typedef を用いて ZIP という型名にする
  • ZIP の変数1つは1件分の郵便番号簿データを格納するものとする
  • どんな型のものをメンバとすべきかはよく考えよう.
    • メンバ名は自分で決めたらよい
    • 住所の文字は英数字が最大200字まで格納できるようにすること(最後にアレが必要だから...)

check ex06b.cに関する注意

  • ソース中に NDATA という定数を定義(#define を使う)し,ZIP の配列を要素数 NDATA で宣言する.
  • 上記のファイルを開く fopen は次のように書けばよい
      FILE *fp;
         :
      if(NULL == (fp = fopen("/roes/sample/takataka/aprog20XY/zipdata", "r"))){
        fprintf(stderr, "ERROR: file not found\n");
        exit(EXIT_FAILURE);
      }
    
  • fscanf の戻り値を利用して,最大 NDATA 件の郵便番号データを読み込めるようにすること.
  • 読み込んだ結果を次のように出力するように作ること.
    • NDATA を 100 とした時:
      読み込んだデータのデータ件数: 100
      0番目: 6148062 京都府八幡市八幡清水井
      99番目: 0440451 北海道虻田郡喜茂別町上尻別
      
    • NDATA を 20000 とした時:
      読み込んだデータのデータ件数: 20000
      0番目: 6148062 京都府八幡市八幡清水井
      19999番目: 1066129 東京都港区六本木六本木ヒルズ森タワー(29階)
      
    • NDATA を 200000 としたとき
      読み込んだデータのデータ件数: 121667
      0番目: 6148062 京都府八幡市八幡清水井
      121666番目: 6520053 兵庫県神戸市兵庫区北山町
      
  • NDATA を大きくすると,プログラムに間違いがないのに実行時に 「Bus Error」,「Segmentation Fault」,「セグメントエラー」といったエラーが出ることがある.これは,ZIP の配列が大きいためである.このようなエラーが出たら,ZIP の配列を宣言する文の前に static をつければ解決する(なぜこのようなことが起こるのか知りたいひとは高橋をつかまえてください).

課題C(takataka) 締切: 来週月曜13時 [edit]

郵便番号簿探索プログラムを作ろう(1)

課題Bのプログラムをもとにして,郵便番号を線形探索するプログラムを作ろう.ただし,ソースファイルは次の3つから成るものとする.

ex06zip.h
課題Bで作ったヘッダファイル.必要に応じて修正を加える.
ex06zip.c
線形探索の関数を定義したソースファイル.
ex06c.c
main関数を定義したソースファイル.

check 線形探索の関数は次の仕様を満たすようにすること

  • 関数名は LSearch とする
  • 引数は,ZIP の配列,その要素数,探索キーの値(郵便番号)の3つ.順序もこの通りとする
  • 戻り値は次のように定める
    • 配列中にキーの値と一致するものが見つかった場合はその要素番号(配列の添字)
    • 見つからなければ -1
  • 探索アルゴリズムは線形探索とする.配列中に同じキー値をもつデータが複数含まれている場合のことは考慮しなくてよい(配列の先頭から探して最初に見つけたものの番号を返すようにすればよい)
  • この関数中ではscanfもprintfも使わない

check ex06c.c については,次のような実行結果となるように作ること.

$ ./ex06c
121667件の郵便番号データを読み込んだで
7桁の郵便番号を入力してね(負の数だと終了) 5202123
5202123 滋賀県大津市瀬田大江町
7桁の郵便番号を入力してね(負の数だと終了) 0010010
0010010 北海道札幌市北区北十条西(1〜4丁目)
7桁の郵便番号を入力してね(負の数だと終了) 9998525
9998525 山形県飽海郡遊佐町直世
7桁の郵便番号を入力してね(負の数だと終了) 1234567
見つからへんかった...
7桁の郵便番号を入力してね(負の数だと終了) 1066129
1066129 東京都港区六本木六本木ヒルズ森タワー(29階)
7桁の郵便番号を入力してね(負の数だと終了) 1066130
1066130 東京都港区六本木六本木ヒルズ森タワー(30階)
7桁の郵便番号を入力してね(負の数だと終了) -1
ばいばい

check プログラムが完成したら,次の2つのものを所定の用紙に書いて提出しなさい(どこが1の解答でどこが2の解答かわかるように,線を引いて番号を書き入れる等の工夫をしてください).

  1. ex06zip.h 中で構造体 ZIP を定義している部分
  2. ex06zip.c 中で線形探索の関数を定義している部分

課題D(TA) 締切:次回実習開始直後 [edit]

郵便番号簿探索プログラムを作ろう(2)

ひとの作ったプログラムを利用して,郵便番号簿を二分探索するプログラムを作ろう.この課題では,次の3つのファイルを入手または作成してプログラムを作る.

zipsearch.h
takatakaが作ったヘッダファイル./roes/sample/takataka/aprog20XY にある.
zipsearch.o
郵便番号データを線形探索する関数,二分探索する関数,等が定義されたソースをコンパイルしてできたオブジェクトファイル.↑と同じ場所にある.
ex06d.c
main関数を定義したソースファイル.自分で作成する.
  • check 課題Cの ex06c.c を ex06d.c にコピーして,zipsearch.h の内容を参考にして書き換えていくのがよいだろう.
  • check 課題Cでは構造体を自分で定義したけれど,zipsearch.o 中の関数を使うためには,zipsearch.h で定義された構造体を使う必要がある.
  • check 線形探索と違い,二分探索は事前準備が必要なことに注意(二分探索するためには,データがあらかじめ...).
  • プログラムの動作は,線形探索のかわりに二分探索をする,ということの他は課題Cと同様でよい.余裕のある人は,/roes/sample/takataka/aprog20XY/zipsearch のように線形/二分探索を切りかえられるようにしたり,探索回数を表示するようにしたらよいだろう.

課題E(TA) 締切:次回実習終了20分前 [edit]

右のリンク先参照 AProg/2016/ex06E

課題S, T and U(おまけ) [edit]

右のリンク先参照 AProg/2016/ex06STU


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-11-08 (火) 11:15:43 (376d)