情報処理Ⅱ 第8回:2003年12月9日(火).

Slides:



Advertisements
Similar presentations
プログラミング 関数編 情報科学科. プログラミングにあたって C 言語では、 main 内に処理を記述 1000 行になるような大きなプログラムでは、 プログラム全体が何をしているのかを把握 することが困難になる 他人が見ると非常に理解しにくい 作成者であっても時が経てば内容を忘れて、他 人が見た時と同じ状況になる.
Advertisements

情報処理Ⅱ 第8回 2004 年 11 月 30 日(火). 2 本日学ぶこと 関数と変数 目的  関数を自分で定義し,変数の利用方法・範囲を明示的に制 限することで,適切な機能分割(モジュール化,再利用) を図る. してはいけないこと  main 関数のみで 100 行以上のプログラム  グローバル変数を駆使するプログラム.
情報処理Ⅱ 第7回:2003年12月2日(火). 問題(授業がつまらない人のため に) ぷよ連結問題 前提 : フィールドを2次元 配列で定義し,各マスの 「ぷよ」を int 型の値で表現 する. ある地点を入力に取り,そ れと連結する「ぷよ」の個 数を求めよ. 消去できる「ぷよ」 (N 個以上 連結するぷよと,それに隣接する特.
2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
【事例演習5】  字句解析     解 説  “ハッシュを用いた字句解析の方法”.
アルゴリズムとデータ構造 第2回 線形リスト(復習).
情報処理Ⅱ 第11回 2004年12月21日(火).
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
情報処理Ⅱ 2006年12月8日(金).
第11回 整列 ~ シェルソート,クイックソート ~
ファーストイヤー・セミナーⅡ 第8回 データの入力.
データ構造とアルゴリズム 第10回 mallocとfree
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
情報処理Ⅱ 2005年12月9日(金).
情報処理Ⅱ 2005年12月22日(木).
第8回 プログラミングⅡ 第8回
アルゴリズムとデータ構造 2011年6月13日
データ構造とアルゴリズム 分割統治 ~ マージソート~.
条件式 (Conditional Expressions)
第4回放送授業.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
情報処理Ⅱ 第9回 2004年12月7日(火).
プログラミング2 関数
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
情報処理Ⅱ 2007年12月3日(月) その2.
第9回関数Ⅰ (簡単な関数の定義と利用) 戻り値.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
情報処理Ⅱ 第14回 2006年1月23日(月).
アルゴリズムとデータ構造 2010年7月26日
情報処理Ⅱ 第2回:2003年10月14日(火).
再帰的手続き.
コンパイラ 2011年10月20日
データ構造とアルゴリズム 第11回 リスト構造(1)
アルゴリズムとプログラミング (Algorithms and Programming)
ポインタとポインタを用いた関数定義.
コンパイラ 2012年10月29日
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
情報処理Ⅱ 第2回 2006年10月13日(金).
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
情報処理Ⅱ 第7回 2004年11月16日(火).
情報処理Ⅱ 2005年10月28日(金).
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
モジュール分割.
コンパイラ 2012年10月11日
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
ソフトウェア工学 知能情報学部 新田直也.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
PROGRAMMING IN HASKELL
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
第10回 関数と再帰.
Q q 情報セキュリティ 第7回:2005年5月27日(金) q q.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
情報処理Ⅱ 小テスト 2005年2月1日(火).
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
情報処理Ⅱ 第3回 2004年10月19日(火).
情報処理Ⅱ 2006年10月20日(金).
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
Presentation transcript:

情報処理Ⅱ 第8回:2003年12月9日(火)

前回の講義の見直し 識別子の宣言(関数・変数の定義)に関する補足 constを含む変数と代入

識別子の宣言に関する補足 グローバル区間に同一の識別子を複数宣言できない. 関数と同じ名前の変数もNG. ブロック内(ローカル)に変数を定義するときは,それより外の識別子と重複してもよい. ブロック内では,重複する外の識別子は使用できない. モジュール化に関して有用なルール. 関数はブロック内で定義できない. 必ずグローバル区間での定義となる. グローバル - global - 大域的 - あらゆるブロックの外 ローカル - local - 局所的 - あるブロックの中

constを含む変数と代入 constを含む型について,オブジェクトの参照はOK. 代入など,左辺値としての使用はよくない(警告). ポインタの代入について const char *p; char *q;としたとき, constなしからconstあり(p = q;)はOK. constありからconstなし(q = p;)はよくない(警告). キャスト演算子による変換(q = (char *)p;)はOK. 記憶域クラスには適用できない(型の一部ではない). x = (static int)y; はNG(コンパイルエラー).

本日のテーマ:再帰(recursion) Cでは,関数の内部で自分自身を呼び出す(再帰呼び出し,recursive call)ような記述ができる. 再帰的(帰納的,循環的)な定義の実装や,バックトラック(backtrack),分割統治法(divide-and-conquer)といった手法に対してよく用いられる. 注意点 無限ループにならないようにする. 再帰を使わないほうがよいこともある.

例題1 カウントダウンするプログラム 自作関数countdownの定義の中で,countdownを呼び出している.

例題1のプロセス状態は? 同一の変数名(x)に対して複数のオブジェクトが生成される点に注意. main countdown num = 3

例題1のバリエーション 出力の位置を変えると,countupになる. 再帰なしのプログラムのほうが,効率はよい. なぜ再帰なしのほうが効率がよいか? …関数呼び出しのコストが大きいから. 「オーバーヘッド」という

再帰的な定義の例(1) 階乗 フィボナッチ数列(例題2) 再帰を用いれば,シンプルに書ける. 0! = 1, 1! = 1 n! = n×(n-1)! (n≧2) フィボナッチ数列(例題2) a1 = 1, a2 = 1 an= an-1 + an-2  (n≧3) 再帰を用いれば,シンプルに書ける. しかしこれらも,whileループのほうが効率がよい.

再帰的な定義の例(2) UNIXのファイル構造 「ディレクトリ」には「ファイル」を配置できる. ファイルには,「通常ファイル」と「ディレクトリ」がある(実際にはもっとさまざまな種類のファイルがある). ディレクトリは「親ディレクトリ」をちょうど1つ持つ. etc X11 Sessions hosts XF86Config / home resolv.conf XF86Config-4 usr

そこで問題 あるディレクトリから下のすべてのファイル名を出力するには? ディレクトリが持つファイルを(1個1個,順に)獲得すし,そのファイル名を出力する. それがディレクトリであれば,(再帰的に)そのディレクトリから下のすべてのファイル名を出力する. 本質的にこれは「木(tree)の探索問題」であり,さまざまなアルゴリズムが知られている.

例題3:ぷよ連結問題 右図のような(2次元)フィールドと,その中の座標を入力に取り,そこと連結する「ぷよ」の個数を求めよ.

フィールドの表現 フィールドは2次元 ⇒2次元配列を使用 色は赤・青・黄と空白 ⇒int型で表現 int field[高さ][幅] = { 0, 0, 3, 0, 0, 0, 1, 3, 2, 0, 0, 1, 3, 2, 3, 2, 2, 2, 3, 2, 2, 3, 3, 3, 1, 1, 2, 3, 1, 3, 1, 1, 2, 2, 3, 3, }; …1 …2 …3 空白…0

再帰の使い方 関数プロトタイプは int consize(int x, int y, int color); 戻り値は, (x, y)と連結していて色がcolorである「ぷよ」の数を返す. フィールド情報は,関数の「外」から与える. 戻り値は, (探索打ち切りの)条件を満たすときは,0 そうでなければ, 1 + consize(x + 1, y, color) + consize(x - 1, y, color) + consize(x, y + 1, color) + consize(x, y - 1, color) : 探索の方向

探索打ち切りの条件 以下のいずれか 探索済みかどうかを記憶するための領域も必要. (x, y)が範囲外 color == 0 field[y][x] != color (x, y)の地点は探索済み 探索済みかどうかを記憶するための領域も必要. int field_checked[高さ][幅]; で確保する.

分割統治法 対象領域を細分化して求め(分割),全体として正しい解になる(統治)ようにする. 例: クイックソート 2 8 5 6 7 3 1 4 「4より小」, 「4と等しい」, 「4より大」に 分ける. 4 7 2 6 1 8 3 5 1 7 8 5 6 4 3 2 1 2 3 4 5 6 7 8

まとめ 再帰的に定義された問題は,再帰呼び出しを用いてプログラムを記述するとうまくいきやすい. 一般に,再帰を用いないほうが効率的である. 関数内のauto変数は,関数呼び出しごとに生成される点に注意.

レポートの補足 「レポートの書き方」を作成したので参考にしてほしい. http://www.wakayama-u.ac.jp/~takehiko/ipii2003/report.pdf 講義のページからリンクしている.

発展的な話題: 再帰は常に解消できるか? 結論から言うと,可能. 方法は… 注意点 反復に置き換える. 簡単な数列の問題は,これで可能. 「スタック」や「リスト」と呼ばれるデータ構造を用いる. 木の探索,ぷよ連結問題,クイックソートともこれで可能. 注意点 自然でない記述になるため,バグが入りやすい. かける手間に対して効率がよくなるかの検討が必要.

発展的な話題: 自分自身を呼び出さない再帰 関数 x が関数 y を呼び出し,関数 y が関数 x を呼び出す場合も再帰という. 例: 再帰下降構文解析 「式」は,「項」,「項+項」,「項+項+項」… のいずれかにより構成される. 「項」は,「因数」,「因数*因数」,「因数*因数」,「因数*因数*因数」…のいずれかにより構成される. 「因数」は,「(式)」もしくは「定数」により構成される. 5 や 1+2*3 はこの意味で式であるが,2++ や (4)) は式ではない.どうすれば判定(解析)できるか? ⇒ 文字列(の先頭位置)を入力に取って,式,項,因数,定数をそれぞれ解析する関数を定義し,必要に応じて互いを呼び出し合えばよい.