1 / 68

コンピュータ基礎演習 −アルゴリズムとデータ構造−

コンピュータ基礎演習 −アルゴリズムとデータ構造−. アルゴリズムの設計と解析. アルゴリズムとは 問題を解くための 論理または手順 データ構造とは 問題を解くための情報をどのような形で 表現・記憶 するか プログラム データ構造を利用して,アルゴリズムを プログラミング言語で表現したもの. プログラミングとは. 問題分析 何をするプログラムを書くのか決める  (プログラム仕様の決定) どんなアルゴリズム,データ構造を使用すればよいかを選択 実際にプログラムを書く プログラムが正しく動くことを保証する (検証). この授業では,

iden
Télécharger la présentation

コンピュータ基礎演習 −アルゴリズムとデータ構造−

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. コンピュータ基礎演習−アルゴリズムとデータ構造−コンピュータ基礎演習−アルゴリズムとデータ構造−

  2. アルゴリズムの設計と解析 • アルゴリズムとは • 問題を解くための論理または手順 • データ構造とは • 問題を解くための情報をどのような形で表現・記憶するか • プログラム • データ構造を利用して,アルゴリズムをプログラミング言語で表現したもの

  3. プログラミングとは • 問題分析 • 何をするプログラムを書くのか決める  (プログラム仕様の決定) • どんなアルゴリズム,データ構造を使用すればよいかを選択 • 実際にプログラムを書く • プログラムが正しく動くことを保証する (検証) この授業では, 適切なアルゴリズム,データ構造を 選ぶ能力を身に付ける.

  4. 良いアルゴリズムの条件 • 信頼性が高い(精度の良い,正しい結果が得られる) • 処理効率が良い(計算回数が少ない,処理速度が速い,大量のメモリ領域を使わない) • 一般性がある(特定の問題だけでなく,他の問題にも適用できる) • 拡張しやすい(仕様変更に対し簡単に修正が行える) • わかりやすい(誰が見ても理解できる.プログラムの保守がしやすい) • 移植しやすい(他のシステムにも少ない労働で稼働させることができる)

  5. プログラミング • 問題分析 • 与えられた問題の意味を正確に理解 • 目的 • 与えられるデータは何か • 求めるべき結果は何か • 要求される精度は • 処理に与えられた計算量は • その他の要素 • そのプログラムは何度ぐらい利用されるか

  6. 処理方法の決定 • 計算方法の選択 • どの方法が与えられた問題の処理に適しているか(アルゴリズム+データ構造) • その方法により所望の精度は得られるか • 計算量の制限は満たしているか • データの入力方法 • データの種類,使用できる入力装置の種類に応じて適当な方法を選ぶ • キーボードからの直接入力 • ディスクからのファイル読み込み • 処理結果の出力方法 • 結果の利用方法,使用できる出力装置の種類

  7. 処理手順の記述 • コーディング • 文法的な誤り→言語処理プログラムによりこの時点で発見できる • プログラムの検査 • 論理的な誤り→事前条件,事後条件の検査 • アルゴリズム設計段階での条件設定 • 中間処理の例外検出 • プログラムの実行

  8. 事前条件と事後条件(1) • 事前条件 (precondition) • プログラムが正しく動作するための前提条件 • 事後条件(postcondition) • プログラムが動作した後に成立する条件 • 不変条件 • プログラムが動作中に成立している条件

  9. 事前条件と事後条件(2) プログラムの起動 プログラムの終了 プログラムの実行中 事前条件 不変条件 事後条件 正しいプログラムとは: 事前条件が成立しているときに起動された場合に, 実行中に不変条件が常に成立しており,かつ, 終了後に事後条件が成立するプログラム

  10. プログラムの検査 • プログラム起動時に事前条件が成立しているか? • プログラム実行中は不変条件が成立しているか? • プログラム終了時に事後条件が成立しているか?

  11. 演習問題1)漸化式 n個の中からr個を選ぶ組み合わせの数 nCr を求める a,b,c の中から2個選ぶ組み合わせは, ab,ac,bc の3通り 一般には, 計算機でこの式を実行した場合,大きい n の値に対しn! がオーバーフローする危険性がある.

  12. 演習問題1)漸化式 例えば, 最終結果はオーバーフローしないが,分子では??? ヒント: int は通常 232(≒約4,000,000,000)まで

  13. 問題を分析する • 組み合わせは漸化式で表現できる 自分自身{nCr}を次数の低い自分自身{nCr-1}で 再帰的に定義

  14. 問題を分析する(2) 漸化式の表現方法 • 繰り返しの利用 • 関数呼び出しのオーバーヘッドが小さい • 複雑な再帰的定義を展開する場合, • プログラムが複雑になる • 2) 再帰呼び出しの利用 •   定義通りにプログラムを組みやすく保守しやすい •  メモリの使用効率が悪い

  15. 問題を分析する(3) 漸化式を繰り返しで表現する場合: 方針)  を初期値とし,それに係数     を    順次掛け合わせていく.    繰り返しの制御には r を利用する. r を1から始めて,繰り返し毎に +1 を加え,    指定した値になれば停止する.

  16. プログラムが正しく動作するためには があらかじめ成立していなければならない 問題を分析する(4) 事前条件 今までの議論が成立するために暗黙的に仮定していたこと 例えば,こういう組み合わせの値は?

  17. 問題を分析する(5) 契約の概念 事前条件を満たした状態でプログラムが呼び出された場合, プログラムは事後条件を満たすことを保証する. この場合の事後条件とは? が正しく計算されること

  18. 繰り返しによる実装例 #include <stdio.h> int combination(int n,int r) { int i,p; p = 1; for (i = 1; i<=r; ++i) { p *= (n-i+1); p /= i; } return p; } int main(void) { int n,r; n = 5; r = 3; printf( "%dC%d=%d\n", n, r, combination(n,r) ); return 0; }

  19. 計算方法の選択方法,考え方 • どの方法が与えられた問題の処理に適しているのか? • アルゴリズム+データ構造 • 疑似コーディング(疑似プログラム) • どのようなアルゴリズムを使えば良いか • ごく大ざっぱなスケッチ,全体像を掴む • 始めは自然言語(日本語等)で • 徐々に事前条件,事後条件を明らかにしつつ,プログラミング言語に置き換え→段階的詳細化 (Stepwise Refinement)

  20. 段階的詳細化(Stepwise Refinement) 問題に対する適切な数学モデルが構築できれば アルゴリズムはそのモデルを使って定式化できる 詳細化の過程で,どのようなデータが必要か?(事前条件) そのデータに対してどのような操作を行うか?(事後条件) データに加える操作が明らかになれば,それを効率良く行う アルゴリズムとデータ表現(データ構造)が決定される.

  21. 問題解決の過程 問題の表現能力 大 問題の記述量  小 問題の表現能力 小 問題の記述量  大

  22. 疑似コーディング • プログラミング言語と自然言語とを利用して,設計の補助として作成するコード 例えば,

  23. データ型とデータ構造 • データ型(type of data) • ある特定言語のデータの型 • 例えば,int, char など • データ構造(data structure) • ある数学モデルを実装するためのデータの集まり • いろいろなデータ型をもつデータの集まり

  24. C言語のデータ型 • 基本型 • 文字型,整数型,実数型 • 構造型 • 配列,構造体,共用体 • ポインタ型

  25. データ構造 • ある数学モデルを実装するための様々なデータ型を持つデータの集まり • リスト(list) • 待ち行列(queue) • スタック(stack) • 木(tree) • ハッシュ表(hash table) • グラフ(graph) 抽象データ型 (Abstract Data Type) =データ構造+手続き これらのデータ構造は,配列型のデータ領域と格納場所を 示す整数型カウンタで実装できる. もちろん,ポインタと構造体を使っても実装できる.

  26. コンピュータ基礎演習 ーC言語の復習:配列ーコンピュータ基礎演習 ーC言語の復習:配列ー

  27. 配列と構造体 • 配列(array) • 同じデータ型を持った要素を集めたもの • 配列の要素は,添字(インデックス,index)により参照可能 • 構造体(structure) • 異なるデータ型を意味的にひとまとまりにしたもの

  28. 配列(C言語) • データ型 配列名 [ 要素数 ]; • 指定されたデータ型が要素数分だけ連続した格納領域の宣言 例)int data[4]; 0〜3番までの4個のint 領域が確保される.

  29. 配列の初期化 • データ型 配列名[要素数] = {定数,定数,…,定数} 例) int data[4] = { 7, 4, 3, 10 };

  30. 演習問題2 • 例えば,最大値を求めるには • 最大値の条件: • 他のすべてのデータより大きい(事後条件) • すべてのデータと比較が必要 疑似言語記述: • m←data[0] • for (I ← 1 .. N-1) if (!(m >= data[I])) m ← data[I] 繰り返し 論理否定 最大値の条件 最大値になるよう修正

  31. 配列データの最大値計算 #include <stdio.h> int main(void) { int data[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; int i, m, n = 10; m = data[0]; for (i=1; i<n; ++i) if (m < data[i]) m = data[i]; printf( "maximum = %d¥n", m ); return 0; } 配列の要素数 疑似言語をC言語 に変換した部分

  32. 課題2 解答例 #include <stdio.h> double average(int cs[],int n) { int i; double sum = 0; /* 合計値の計算 */ for (i=0; i<n; ++i) sum += cs[i]; return sum/n; /* 合計/要素数 */ } int main(void) { /* データの初期化 */ int cs[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /* 平均を計算する関数の呼出と平均値の出力 */ printf( "average = %lf¥n", average(cs,10) ); }

  33. 配列と次元(2次元配列,3次元配列) • 次元とは,配列に含まれる要素を識別するために必要な添え字の個数のこと データ型 配列名[要素数] ;1次元配列 データ型 配列名[要素数][要素数]     ;2次元配列 データ型 配列名[要素数][要素数][要素数] ;3次元配列 例)3人で4回トランプをした場合の得点表 int score[3][4]; 整数型2次元配列で表現

  34. 2次元配列 列 0    1   2    3 行 0 1 2 列にゲームの回数,行にプレイヤー メモリ(計算機)の中ではどんな形で格納? int score[3][4]; 低位アドレス 高位アドレス

  35. 2次元配列の初期値設定 データ型 配列[要素数][要素数] = { {定数,定数,… , 定数}, {定数,定数, … , 定数}, ・・・・・・ {定数,定数,… , 定数} }; int score[3][4] = { { 7, 45, 3, 10 }, { 11, -3, 8, 17 }, { 90, 41, 32, 100 } };

  36. 演習問題3 • 4行4列のデータを入力し,縦計,横計,総合計を求め,表形式で出力せよ ○問題の分析  縦計,横計のデータ領域も必要であるから,  5行5列の配列を用意する. 基本方針)  1)16個のデータを配列に入力  2)縦計,横計,総合計を求める  3)結果の表形式での表示 ☆演習課題2の応用,各要素に対して繰り返し(for文で)演算を行う

  37. 疑似コーディング • 16個のデータを配列に入力 • 4行4列のデータ入力であり,各行は同じ形式としてよいから,まず1行分の入力を4回行うと考える 1-1) for (i ← 0 .. 3) 1-2)1行分(data[i])を入力 1行には4列分のデータがある  故に data[i][0], data[i][1], data[i][2], data[i][3]  にデータが格納されるようにする

  38. 疑似コーディング(2) • 1行分を入力する • 行の場合と同様に列も4回繰り返し 1-1) for (i ← 0 .. 3) 1-2)1行分(data[i])を入力 繰り返し回数を覚えている 変数は違うものを利用 1-1) for (i ← 0 .. 3) 1-2) for (j ← 0 .. 3) 1-3) 1つのデータ(data[i][j])を入力する

  39. 疑似コーディング(3) • 1つのデータを入力する • Cの標準ライブラリscanf関数を利用する int i; float f; double d; scanf( "%d", &i ); /* 変数 i に整数値を入力する */ scanf( "%f", &f ); /* 変数 f に単精度実数値を入力する */ scanf( "%lf", &d); /* 変数 d に倍精度実数値を入力する */

  40. 疑似コーディング(4) • 縦計,横計,総合計を求める • <縦計の計算> • <横計の計算> • 縦計の場合と行と列を入れ替える 1-1) for (j ← 0 .. 3) 1-2) data[4][j] ← 0 1-3) for (i ← 0 .. 3) 1-4) data[4][j] += data[i][j]

  41. 疑似コーディング(5) • <総合計の計算> • 縦計か横計が得られれば計算できる. • 事後条件 • 総合計=Σ縦計=Σ横計 • 縦計の総和と,横計の総和を求め比較 • 正しい総合計ならば data[4][4] に格納 1-1) tate ← 0, yoko ← 0 1-2) for (i ← 0 .. 3) 1-3) tate += data[4][i], yoko += data[i][4] 1-4) if (tate = yoko) data[4][4] ← tate もちろん tate = yoko なので yoko でもよい

  42. 事後条件を満たさない場合 • プログラムが動作終了した時に,事後条件を満たさないプログラムは,欠陥品である • 責任の所在 • 事前条件が満たされていない • プログラムを起動した側(ユーザ)の責任 • 事前条件は満たされている • プログラム側の責任

  43. 事前条件 • 演習課題3では明確にしていない • 設計者が設定する必要がある • データの精度,有効桁数など 例えば,以下のような条件のプログラム 事前条件:データ入力の桁数1桁から3桁までの正の整数      データは16個なければならない 事後条件:総合計=Σ縦計=Σ横計

  44. コンピュータ基礎演習 ーC言語復習:関数ーコンピュータ基礎演習 ーC言語復習:関数ー 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp

  45. サブプログラム • 大きなプログラムでは,扱う値は異なっても,同一の処理が異なる位置に現れることがある. • このような場合,同一の処理を別途記述し,元のプログラムからその処理部分を呼び出すようにできると便利 独立した処理部分:サブプログラム,モジュール          サブルーチン,関数などと呼ばれる

  46. Cプログラムの特徴 • 関数の集合体 • 言語としてはシンプルな部類 • main関数,printf関数, scanf関数など 返値のデータ型 関数名(仮引数の型と変数宣言の並び) {   内部変数の宣言;   実行部分(処理内容); } 関数の定義 仮引数:呼び出し側から与えられるデータを受け取る変数

  47. main関数 • プログラムが起動した時に最初に呼ばれる関数 • 通常,プログラムはオペレーティングシステムから起動される. • main関数の返値は起動したオペレーティングシステムに渡される. int main(int argc,char *argv[]) {  処理内容; return 0; → プログラムが正常終了した時は } 0 を戻す OSから渡されるデータ

  48. 例)関数         を求める double F(double x) → 関数Fの宣言,仮引数xのデータ型宣言 { → 関数Fの定義開始 double f; → 倍精度実数型変数fの宣言 f = 2*x*x+6*x+4; → 関数Fの計算 return f; → 関数Fの計算結果を呼び出し側に戻す } → 関数Fの定義終了 関数(サブプログラム等を含む)の利点:  ・関数の外部仕様(事前条件,事後条件)だけを知っておけば良い  ・関数の内部仕様(実装方法や不変条件)は知らなくて良い 例えば: sin関数や cos関数などの実装方法を知っている人は?

  49. 関数の呼び出し方 関数名(実引数の並び); 実引数   :呼び出し側(例えば,main関数)で関数に        与えたデータのこと. 実引数の並び:実引数をカンマ(,)で区切ったもの 例: F(x,4);

  50. 関数の返値 • 呼び出した関数から戻ってくる時に値を返すことができる. return 式 ; 値を返さない場合(例えば,void型関数)   「式」は省略可能(return自体も省略可能)

More Related