関数の再帰呼び出しとは ハノイの塔 リダイレクト レポート課題

Slides:



Advertisements
Similar presentations
知能情報工学演習 I 第 12 回( C 言語第6 回) 課題の回答 岩村雅一
Advertisements

配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
関数(1) 第11回 [6月29日、H.16(‘04)] 今日のメニュー 1 前回の課題 2 前回の宿題 3 いろいろな関数の演習 4 課題
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
第14章 ファイル操作 (コマンドプロンプト版)
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
プログラミング演習(2組) 第12回
プログラミング論 I 関数の再帰呼び出し
Excelによる3-D/等高線グラフの描画 2変数関数の描画 Excel によるグレイスケールマップ風描画
Excelによる3-D/等高線グラフの描画 2変数関数の描画 Excel によるグレイスケールマップ風描画
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
問題 1 フィボナッチ数列 xn は次で定義される。
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月6日、H.16(‘04)] 今日のメニュー 1 前回の課題の復習
Stack & Queue & List 3.
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
Cプログラミング演習.
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
Cプログラミング演習 第7回 メモリ内でのデータの配置.
プログラミング演習I 2003年6月25日(第10回) 木村巌.
プログラミング2 関数の再帰呼び出し
高度プログラミング演習 (03).
知能情報工学演習I 第12回(後半第6回) 課題の回答
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
第14章 ファイル操作 (コマンドプロンプト版)
プログラムの制御構造 配列・繰り返し.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
演習0 func0, func1, func2を作成せよ. main()関数の中で,func0()を呼び出しを実行せよ.
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
演習07-0 “Hello\n” “World!\n”と
Cプログラミング演習資料.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
プログラミング序論演習.
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
Excelによる3-D/等高線グラフの描画 2変数関数の描画 Excel によるグレイスケールマップ風描画
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
アルゴリズムとデータ構造 補足資料9-1 「ハノイの塔」
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
Inline 展開のアルゴリズム 長谷川啓
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
プログラミング2 関数の再帰呼び出し
知能情報工学演習I 第12回( C言語第6回) 課題の回答
高度プログラミング演習 (07).
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
Cプログラミング演習資料.
第10回 関数と再帰.
プログラミング入門2 第5回 配列 変数宣言、初期化について
第4回 配列.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
岩村雅一 知能情報工学演習I 第13回(後半第7回) 岩村雅一
第5回 配列.
プログラミング演習I 補講用課題
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
第1章 文字の表示と計算 printfと演算子をやります.
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
Presentation transcript:

関数の再帰呼び出しとは ハノイの塔 リダイレクト レポート課題 第10章 関 数 関数の再帰呼び出しとは ハノイの塔 リダイレクト レポート課題

関数の再帰呼び出し nの階乗(有効数字15桁) fact.c #include <stdio.h> double fact(int n) { if (n==0) return 1; printf("fact:%u, n=%d\n", frac, n); return n*fact(n-1); } int main(int argc, char *argv[]) int n=3; if (argc >1) sscanf(argv[1], "%d", &n); printf("fact:%u, %d!=%.0f\n", fact, n, fact(n)); return 0; 自分自身を呼び出す 数学的帰納法に良く似ている

fact(3)の呼び出しの展開 fact(3) fact(n)[n==3] 6 3*fact(2) fact(n)[n==2] 2 1 fact(n)[n==0] 1 1

ハノイの塔 3本の棒と大きさの異なる n枚の円盤がある。 すべての円盤は1番の棒に、上から下に大きくなるように入れてある。 1回につき1つの円盤を動かし、2番の棒に移し換える。 3つの棒はどのように利用しても良い。 どの時点、どの棒についても、大きな円盤が小さな円盤の上にきてはいけない。

1~3枚の場合(1から2に移す) 1枚 2枚 3枚 1 2 3 1 2 3 一番下を動かす前後に注目 1 2 3

ハノイの塔のアルゴリズム 上の n-1枚を3番目の棒(空き地)に移す 一番下の1枚を2番目の棒(目的地)に移す 1枚のときは単に

PAD src+dst+tmp = 1+2+3 = 6 の関係式より tmp = 6 - src - dst hanoi(n-1,src,tmp,dst) hanoi(1,src,dst,tmp) hanoi(n-1,tmp,dst,src) hanoi(n,src, dst,tmp) n > 1 printf("%d → %d\n", src, dst) 目的地 空き地 src+dst+tmp = 1+2+3 = 6 の関係式より tmp = 6 - src - dst を用いて第4引数tmpをなくすことも可能

ハノイの塔 #include <stdio.h> void hanoi(??????) { ?????? } int main(int argc, char *argv[]) int n=3; if (argc > 1) sscanf(argv[1], "%d", &n); hanoi(n, 1, 2, 3); return 0;

リダイレクト(出力編) コマンドプロンプトにおいて、標準出力(ディスプレイ出力)をファイル出力に切り替える方法 例えば、階乗計算 fact.exe で10! を求める場合、 Z:\nyumon2>fact 10 > fact10.txt とすることで、画面に表示されていたものが、テキストファイルとして保存される。 レポートの課題などで長い出力結果の一部をレポートに添付する場合、画面上で結果の先頭部分が消えてしまう時でも、リダイレクトにより結果をファイルに保存すれば大丈夫。

演習問題12.2 (1次元化版) #include <stdio.h> #define NROW 3 #define NCOL 3 #define IDX(i,j) ((i)*NCOL+(j)) void sum_ave(int m, int n, double a[], double *s, double *av); int main(void) { double s, av; double a[NROW*NCOL] = {3.24, 1.76, 5.32, 2.37, 4.33, 1.26, 1.86, 1.86, 3.64}; sum_ave(NROW, NCOL, a, &s, &av); printf("総和 = %7.2f, 平均 = %7.2f¥n", s, av); return 0; } void sum_ave(int m, int n, double a[], double *s, double *av) int i, j; *s = 0; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) *s += a[IDX(i,j)]; *av = *s/(m*n); 配列要素の数値の総和と 平均値を計算する関数 総和の計算 平均値の計算

演習問題12.3 (1次元化版) #include <stdio.h> #define N 3 #define IDX(i,j) ((i)*N+(j)) void sum(int m, int n, int x[], int y[], int z[]); void diff(int m, int n, int x[], int y[], int z[]); void prod(int m, int n, int x[], int y[], int z[]); void disp_2D_array(int m, int n, int x[]); int main(void) { int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int b[] = {11, 12, 13, 14, 15, 16, 17, 18, 19}; int c[N*N]; disp_2D_array(N, N, a); disp_2D_array(N, N, b); sum(?????????); disp_2D_array(N, N, c); diff(?????????); disp_2D_array(N, N, c); prod(?????????); disp_2D_array(N, N, c); return 0; }

演習問題12.3 (つづき) i = 1...m j = 1...n 行列の和 i = 1...m j = 1...n 行列の差 行列の積 void sum(int m, int n, int x[], int y[], int z[]) { ???...??? } void diff(int m, int n, int x[], int y[], int z[]) void prod(int m, int n, int x[], int y[], int z[]) int i, j, k; for (i = 0; i < ?; i++) { for (j = 0; j < ?; j++) { z[IDX(i,j)] = 0; for (k = 0; k < ?; k++) z[IDX(i,j)] += ???????????????; void disp_2D_array(int m, int n, int x[]) i = 1...m j = 1...n 行列の和 i = 1...m j = 1...n 行列の差 行列の積 i, j = 1...m

演習問題12.4 (1次元化版) 掃出法 #include <stdio.h> #define N 3 #define IDX(i,j) ((i)*(N+1)+(j)) void sweep_out(int n, double a[]); void disp_2D_array(int m, int n, double a[]); int main(void) { double a[N*(N+1)] = {2,3,1,-1, 3,1,2,7, 1,2,3,6}; disp_2D_array(???????); sweep_out(???); return 0; } 掃出法

演習問題12.4 (つづき) void sweep_out(int n, double a[]) { 演習問題12.4 (つづき) void sweep_out(int n, double a[]) { int i, j, k; double w; for (k = 0; k < n; k++) { w = a[IDX(k,k)]; for (j = 0; j < n+1; j++) a[IDX(k,j)] /= w; for (i = 0; i < n; i++) { if (i != k) { w = a[IDX(i,k)]; for (j = 0; j < n+1; j++) a[IDX(i,j)] -= w * a[IDX(k,j)]; } void disp_2D_array(int m, int n, double a[]) ???...??? k行目の成分をその対角成分で割る 掃き出し操作

第2回 レポート(任意) 課題 課題:教科書p.114の演習問題12.3 または 12.4 提出期限:2010年11月26日(金) 12:50 提出場所:ネットワーク実験室(1)の入口近くの箱 今回のレポートでは以下の項目をいれること。 学籍番号、氏名 問題番号 ソースリスト 実行結果 感 想(5行以上) レポートのファイルは 保存しておくこと レポートサンプルを参照のこと

本日のパズル 次のプログラムは何を出力するか #include <stdio.h> #define PRINT(x,y) printf("%d\t%d\n",x,y) main() { int x, y; x=y=0; while ( y<10 ) ++y; x += y; PRINT(x,y); while ( y<10 ) x += ++y; for ( y=1; y<10; y++ ) x=y; } 1 2 3