2 部データ構造とアルゴリズムI レポート課題

本講義では 2 通のレポートで評価します。 レポートは A4 縦の様式で PDF 形式で作成して下さい。 またプログラムは C 言語で作成しなさい。

変更履歴

2025/5/22 18:10:00
課題1初出
2025/5/23 02:00:00
課題1締め切り年の訂正
2025/5/24 02:00:00
配布ファイル kadai2025.zip に誤りがありましたので、修正版を kadai20252.zip として配布します。 間違っているのは、kadai13.c の下の行の引数が足りませんでした。

      p = find(item[i].day, item[i].period, list);
    
kadai20252.zip をダウンロードせず、上記の部分だけ訂正して使用しても構 いません。

課題1

レポート締切日: 2025年6月4日(水)23:59
提出先: BOX https://tdu.app.box.com/f/8528eb7aee83435893b4ca0846e9350a にファイル名を 学籍番号-1.pdfとして、 アップロードすること

解答法として、分割コンパイルによる別ファイルにプログラムを書く方 法と、下記のテストプログラムに関数を追記する方法の二通りがあるが、 どちらでも良い。 プログラムの解説は、自分で作成した関数について行うこと。 こちらで提供したテストプログラムの説明は基本的には不要である。 但し、自分で作成した関数を説明するのに必要な内容には言及すること。 また前問で作成した関数については自由に使用して良い。

問題とテストプログラムの改変は不合格である。 なお、こちらの提供したファイルやMakefile は使用してもしなくても良い。 また、プログラムを結合するためなどのやむを得ない必要な変更(include の代わりにプログラムを埋め込むなど)は許される。

問題の最後に、本課題で必要なヘッダファイル kadai1.h と Makefile を示す。また、 Visual Studio のソリューションを含む圧縮ファイルを置く。 課題で作成する関数は「関数名.c」というファイルに入れられる前提としている。

なお、課題1だけはレポートは締め切り後も提出できます。 同じファイル名で複数のバージョンが存在できます。 締め切り内に採点可能なレポートがある場合は、最も締切に近いものだけを採 点します。 締め切り内に有効なレポートがない場合、最も新しいレポートを遅れレポー トとして減点の上採点します。


kadai1.h には本課題に必要な宣言が含まれている。 まず、 構造体 Kamoku は次のように定義されている。


typedef struct kamoku {
  int day;
  int period;
  char* name;
} Kamoku;

またグローバル変数として、 Kamoku の配列 list (番兵として最後に day=-1 となっている要素が含まれる) と 0→ sun, 1→ mon, ..., 6→ sat という、数から曜日を得る配列 youbi が次のように extern されている。


extern Kamoku list[];
extern char* youbi[];

この他、課題で必要な、関数のプロトタイプ宣言が含まれている。 また、kadai1.c には list, youbi の定義が含まれているため、 各問題で作成したプログラムを実行するには kadai1.c を結合する必要があ る。

問題1-1

Kamokuのポインターを受け取り、メンバーのうちの day については対応する youbi 、 period はそのまま、 name は文字列として並べて表示する void printkamoku(Kamoku *p) を printkamoku.cというファイルに作成せよ。

これと、下記のテストプログラム, kadai1.h, kadai1.c を結合して実行し、出 力結果を示せ。

kadai11.c


#include <stdio.h>
#include "kadai1.h"

int main(void){
  Kamoku *p;
  for(p=list; p->day!=-1; p++){
    printkamoku(p);
    printf("\n");
  }
  return 0;
}
出力例1-1
thu 6 データ構造とアルゴリズム
sat 3 マルチメディア表現技術の基礎および演習
sat 4 コンピュータ基礎および演習III
sat 5 微分方程式I
mon 6 情報通信基礎実験I
tue 6 基礎情報数学B(確率と情報)
fri 6 信号理論(NC)
sat 6 微分方程式I
mon 7 情報通信基礎実験I
tue 7 エレクトロニクスの基礎
wed 7 コンピュータ構成と機械語
thu 7 電磁気学の基礎および演習
fri 7 電磁気学の基礎および演習

問題1-2

二つのKamokuを指すポインタを与えると、 日曜日を起点として、授業実施時間が順に並んでいる(曜日が早い、時限が 早い)時は負の整数、 逆順に並んでいる時は正の整数、 同じ時間であれば0を返す int compkamoku(Kamoku *p, Kamoku *q) 関数を作成せよ。 この関数のファイル名を compkamoku.c とする。

これと、下記のテストプログラム, kadai1.h, kadai1.c, printkamoku.cを 結合して実行し、出力結果を示せ。

kadai12.c


#include <stdio.h>
#include "kadai1.h"

int main(void) {
    Kamoku* p;
    Kamoku* q;
    int result;
    for (p = list; (q=p+1)->day != -1; p++) {
        printkamoku(p);
        printf("は");
        printkamoku(q);
        result = compkamoku(p, q);
        if (result < 0) {
            printf("の前");
        }
        else if (result == 0) {
            printf("と同じ");
        }
        else {
            printf("の後ろ");
        }
        printf("\n");
    }
    return 0;
}
出力例1-2
thu 6 データ構造とアルゴリズムはsat 3 マルチメディア表現技術の基礎および演習の前
sat 3 マルチメディア表現技術の基礎および演習はsat 4 コンピュータ基礎および演習IIIの前
sat 4 コンピュータ基礎および演習IIIはsat 5 微分方程式Iの前
sat 5 微分方程式Iはmon 6 情報通信基礎実験Iの後ろ
mon 6 情報通信基礎実験Iはtue 6 基礎情報数学B(確率と情報)の前
tue 6 基礎情報数学B(確率と情報)はfri 6 信号理論(NC)の前
fri 6 信号理論(NC)はsat 6 微分方程式Iの前
sat 6 微分方程式Iはmon 7 情報通信基礎実験Iの後ろ
mon 7 情報通信基礎実験Iはtue 7 エレクトロニクスの基礎の前
tue 7 エレクトロニクスの基礎はwed 7 コンピュータ構成と機械語の前
wed 7 コンピュータ構成と機械語はthu 7 電磁気学の基礎および演習の前
thu 7 電磁気学の基礎および演習はfri 7 電磁気学の基礎および演習の前

問題1-3

Kamokuの配列 array の中から、曜日番号、時限を指定して、 それに適合した Kamoku のポインタを返す Kamoku* find(int day, int period, Kamoku* array) 関数を作成せよ。 なお、 array のデータの終わりには、番兵として day に -1 が入ってい るとし、見つからなかった場合は NULL を返すとする。 この関数のファイル名を find.c とする。 (NULL は stdlib.h に定義されているものとする)。

これと、下記のテストプログラム, kadai1.h, kadai1.c, printkamoku.cを 結合して実行し、出力結果を示せ。

kadai13.c


#include <stdio.h>
#include "kadai1.h"
typedef struct jigen {
    int day;
    int period;
}Jigen;
int main(void) {
    Jigen item[] = { {4,6},{2,7},{3,6}, { 6,3 },{-1} };
    Kamoku* p;
    int i;
    for (i = 0; item[i].day!= -1; i++) {
        p = find(item[i].day, item[i].period, list);
        if (p == NULL) {
            printf("無し");
        }
        else {
            printkamoku(p);
        }
        printf("\n");
    }
    return 0;
}
出力例1-3
thu 6 データ構造とアルゴリズム
tue 7 エレクトロニクスの基礎
無し
sat 3 マルチメディア表現技術の基礎および演習

問題1-4

番兵として day=-1 である Kamoku の配列を与えると、 下記の出力例のようなフォーマットの時間割表を表示する void printtable(Kamoku* array) 関数を作成せよ。

フォーマット例
sun		mon		tue		wed		thu		fri		sat		
1     	    	    	    	    	    	    	
2     	    	    	    	    	    	    	
3     	    	    	    	    	    	マルチメ	
4     	    	    	    	    	    	コンピュ	
5     	    	    	    	    	    	微分方程	
6     	情報通信	基礎情報	    	データ構	信号理論	微分方程	
7     	情報通信	エレクト	コンピュ	電磁気学	電磁気学	    

最上部に曜日の文字列、左に時限(1-7)を表示する。 各科目名は printf("%.12s\t",p == NULL?"        ":p->name) で表示すると良い

これと、下記のテストプログラム, kadai1.h, kadai1.c を 結合して実行し、出力結果を示せ。

kadai14.c


#include "kadai1.h"
int main(void) {
  Kamoku list2[]={
    {6,3,"情報通信ネットワークの基礎および演習"},
    {6,4,"情報システムの基礎および演習"},
    {1,6,"情報通信基礎実験II"},
    {2,6,"エレクトロニクスの応用"},
    {4,6,"信号システム解析(NC)"},
    {5,6,"論理回路および論理設計(NC)"},
    {1,7,"情報通信基礎実験II"},
    {2,7,"基礎情報数学C(代数と符号)"},
    {3,7,"インターネットプログラミング"},
    {4,7,"電磁気学の応用"},
    {5,7,"通信工学の基礎"},
    {-1}};
  printtable(list);
  printtable(list2);
  return 0;
}
出力例1-4
sun		mon		tue		wed		thu		fri		sat		
1     	    	    	    	    	    	    	
2     	    	    	    	    	    	    	
3     	    	    	    	    	    	マルチメ	
4     	    	    	    	    	    	コンピュ	
5     	    	    	    	    	    	微分方程	
6     	情報通信	基礎情報	    	データ構	信号理論	微分方程	
7     	情報通信	エレクト	コンピュ	電磁気学	電磁気学	    	
sun		mon		tue		wed		thu		fri		sat		
1     	    	    	    	    	    	    	
2     	    	    	    	    	    	    	
3     	    	    	    	    	    	情報通信	
4     	    	    	    	    	    	情報シス	
5     	    	    	    	    	    	    	
6     	情報通信	エレクト	    	信号シス	論理回路	    	
7     	情報通信	基礎情報	インター	電磁気学	通信工学

kadai1.h


typedef struct kamoku {
  int day;
  int period;
  char* name;
} Kamoku;

extern Kamoku list[];
extern char* youbi[];

void printkamoku(Kamoku *k);
int compkamoku(Kamoku* p, Kamoku* q);
Kamoku* find(int day, int period, Kamoku* list);
void printtable(Kamoku* l);

kadai1.c


#include "kadai1.h"
char* youbi[]={"sun","mon","tue","wed","thu","fri","sat"};
Kamoku list[] = { {4,6,"データ構造とアルゴリズム"},
		   {6,3,"マルチメディア表現技術の基礎および演習"},
		   {6,4,"コンピュータ基礎および演習III"},
		   {6,5,"微分方程式I"},
		   {1,6,"情報通信基礎実験I"},
		   {2,6,"基礎情報数学B(確率と情報)"},
		   {5,6,"信号理論(NC)"},
		   {6,6,"微分方程式I"},
		   {1,7,"情報通信基礎実験I"},
		   {2,7,"エレクトロニクスの基礎"},
		   {3,7,"コンピュータ構成と機械語"},
		   {4,7,"電磁気学の基礎および演習"},
		   {5,7,"電磁気学の基礎および演習"},{-1} };

Makefile

$(CC) -o $@ $^の $(CC) の前には TAB 記号が一つ だけ入っていることに注意する。これが空白記号に置き換わっていると動作しない。


kadai14.exe: kadai14.o kadai1.o printtable.o
	$(CC) -o $@ $^
kadai13.exe: kadai13.o kadai1.o find.o printkamoku.o
	$(CC) -o $@ $^
kadai12.exe: kadai12.o kadai1.o compkamoku.o printkamoku.o
	$(CC) -o $@ $^
kadai11.exe: kadai11.o kadai1.o printkamoku.o
	$(CC) -o $@ $^
kadai11.o: kadai1.h
kadai12.o: kadai1.h
kadai13.o: kadai1.h
kadai14.o: kadai1.h
printkamoku.o: kadai1.h
compkamoku.o: kadai1.h
find.o: kadai1.h
printtable.o: kadai1.h

Visual Studio での開発法

下記の操作をしたものをkadai20252.zipとし てダウンロードできます。 ダウンロードしたzipファイルをすべて解凍して、中の sln ファイルをダブ ルクリックすると使用できます。

  1. プロジェクトを作成する時に、プロジェクト名を kadai11 とし、ソリュー ション名は別に与える(例えばalgo2025など)
  2. プロジェクト kadai11 には、ソースファイルとして、新しい項目に kadai11.c を入れる。
  3. プロジェクト kadai12, kadai13, kadai14 をソリューションに追加す る。
  4. それぞれのプロジェクトに kadai12.c, kadai13.c, kadai14.c をソー スファイルに入れる。
  5. ソリューションを右クリックして 「エクスプローラーでフォルダーを開く」
  6. kadai フォルダを新規に作成する
  7. kadai フォルダに kadai1.h, kadai1.cを入れる。 また、printkadai.c, compkadai.c, find.c, printtable.c という名前の 空のファイルを、「新規作成→テキストドキュメントで作成して、名前の変更」 で作成する。これが終わったらエクスプローラーの画面を消して良い。
  8. 4つのプロジェクトそれぞれを右クリックして、プロパティを選ぶ。
    1. C/C++ の項目の最上段の「追加のインクルードディレクトリ」で <編集…>を選択し
    2. 入力欄に「$(SolutionDir)kadai」を入力し、Okを押す
    3. プロパティの Okを押す
  9. 4つのプロジェクトそれぞれで、 「ヘッダファイルを右 クリック→追加→既存のファイル」で kadai フォルダから kadai1.h を選び、 さらに、各プロジェクトで必要なファイルを「ソースファイルを右 クリック→追加→既存のファイル」 で追加する。
  10. 実行するプロジェクトを切り替えるには、実行したいプロジェクトを右クリックして「スタートアッププロジェクトに設定」を選ぶ

レポート作成上の注意

  1. レポートはグラフの表現など特殊な事情がない限り、必ず白黒で作成する こと。
  2. プログラミングのレポートでは必ずプログラムの説明をすること。その時 に、一行一行を日本語に直訳するのではなく、プログラムを機能毎に区分し、 機能の実現方法を説明すること。 プログラムに一行ずつコメントを入れてもプログラムの説明とは見なしません。
  3. 「問題を解きなさい」という問に対して「解きました。合ってました」は 正解ではありません。 「プログラムを作りなさい」という問題については、作成の手順の説明をする こと。 「テストしなさい」という問題についてはテストの手法、合否判定の基準、結 果の検討などを説明しなさい。
  4. プログラムが短くて説明がしづらい場合は、ポインタなどの関係を図示す るなどして工夫してください。
  5. 出力例は個々に異なりますので、手計算であらかじめ正しい値の求め方を 示し、値を提示してテストの合否を判定しなさい。
  6. レポートは手書きでも良いですが、プログラムの実行結果だけは必ずコン ピュータの出力の印刷(スクリーンショット)にして下さい。
  7. 考察は必ず書いて下さい。ネタがない人は以下を参考にして下さい。

なお、写したと思われるほど酷似したレポートが複数提出された場合、原著が どれかの調査を行わず、抽選で一通のレポートのみを評価 の対象とし、他は提出済みの不合格レポートとして再提出は課しません。 自分で意図せずに他人にコピーされてしまった場合も同様ですので、レポート の取り扱いについては十分に注意して下さい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科