第8回 データを収納する (スタックとキュー)

Slides:



Advertisements
Similar presentations
プログラミング第5回 1 while ループ 文字列の操作
Advertisements

プログラミング実習 1 ・ 2 ク ラス 第 2 週目 担当教員 : 渡邊 直樹. 課題 2 ● 2 × 2型行列の固有値, 固有ベクトルを求め る EigMatrix.java というプログラムを作成せ よ。 ● 行列の各要素はコマンド・プロンプトから入力 ● 計算した結果もコマンド・プロンプトに表示.
Generic programming と STL
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
情報処理演習C2 ファイル操作について (2).
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第4回 配列(2) 情報・知能工学系 山本一公
プログラミング言語としてのR 情報知能学科 白井 英俊.
IO - 入出力 小西 亨.
第11回 整列 ~ シェルソート,クイックソート ~
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
~手続き指向からオブジェクト指向へ(Ⅰ)~
第2章 数値の入力と変数 scanfと変数をやります.
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
プログラミング基礎I(再) 山元進.
プログラミング基礎I(再) 山元進.
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
情報工学概論 (アルゴリズムとデータ構造)
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
プログラミング論 II 電卓,逆ポーランド記法電卓
アルゴリズムと データ構造 第4回 スタック・キュー.
第20章 Flyweight ~同じものを共有して無駄をなくす~
情報 第2回:状態遷移 その2.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
情報処理技法 (Javaプログラミング)2 第2回 前期の復習(2)
第13回 ハッシュテーブルを使ったプログラム ~高速に検索するには?~.
第11回 アプリケーションの構成 ~CUI自動販売機の完成!~.
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
サブゼミ第9回 実装編③ 永続化とjava.ioパッケージ.
オブジェクト・プログラミング 第12回 状態遷移図 シーケンス図.
オブジェクト指向 プログラミング 第二回 知能情報学部 新田直也.
第1回 プログラムの基本 他人が読めるプログラムを書く.
アルゴリズムとデータ構造1 2005年7月1日
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.
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
プログラミング 3 スタックとキュー.
オブジェクト・プログラミング 第8回.
明星大学 情報学科 2012年度 後期   情報技術Ⅱ   第8回
アルゴリズムとデータ構造 2011年7月8日課題の復習
スタックとキュー データ構造とプログラミング (第5回).
オブジェクト プログラミング 第2回 プログラムの基本.
統計ソフトウエアRの基礎.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング演習I 2003年7月2日(第11回) 木村巌.
Webアプリケーションと JSPの基本 ソフトウェア特論 第4回.
アルゴリズムとデータ構造 2012年7月2日
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
プログラミング入門 電卓を作ろう・パートI!!.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
暗号技術 ~JAVAプログラム②~ (6週目)
アルゴリズムとデータ構造 2011年6月28日
サブゼミ第7回 実装編① オブジェクト型とキャスト.
第11回放送授業.
アルゴリズムとデータ構造 2013年7月2日
情報処理Ⅱ 第7回 2004年11月16日(火).
アルゴリズム入門 (Ver /10/07) ・フローチャートとプログラムの基本構造 ・リスト ・合計の計算
コンパイラ 2012年10月11日
プログラミング 4 文字列.
ソフトウェア工学 知能情報学部 新田直也.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
データ構造と アルゴリズムI 第三回 知能情報学部 新田直也.
TList リスト構造とは? 複数のデータを扱うために、 データの内容と、次のデータへのポインタを持つ構造体を使う。
第2章 数値の入力と変数 scanfと変数をやります.
オブジェクト・プログラミング 第10回 オブジェクト指向設計のキモ.
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
情報処理技法(Javaプログラミング)1 第8回 同じ処理を何回も繰り返すには?
Presentation transcript:

第8回 データを収納する (スタックとキュー) オブジェクト・プログラミング 第8回 データを収納する (スタックとキュー)

本日の目標 データを収納する2つのデータ構造 (スタック、キュー)の概念を説明できるようになる。 スタック、キューを使う利点を説明できるようになる。 スタック、キューを配列を使って実装できるようになる。

今日登場する新しいオブジェクト(1) 「商品」クラス 「商品情報」は単に情報だけだった。 今日は実際の「商品」を扱う ただし、今日は商品の属性を 「製造日」 だけとします。

今日登場する新しいオブジェクト(2) 「お金」クラス 硬貨一つ一つがオブジェクトと考える ただし、今日はお金の属性を 「値」 だけとします。 値は100円,10円などが入ります。 100 50 10

今日考えること① 問題:商品の補充と販売をできるようにする。 商品を収納しておくFolderが必要です。

今日考える2種類の収納パターン 後入れ先出し方式 先入れ先出し方式

後入れ先だし方式(スタック) 商品Folder 補充する 販売する 後から入れたものは、列の先頭に挿入される。 取り出すときは、列の先頭から ※昔のコンビニのジュース販売方式 これでは、列の最後に入れられたら、取り出される 機会がほとんどなくなってしまう!

先入れ先出し方式(キュー) 商品Folder 販売する 補充する 後から入れたものは、列の最後に挿入される。 取り出すときは、列の先頭から ※いまのコンビニのジュース販売方式 古いものから取り出されるので、商品を販売するの に向いている。

キューを配列を使って作る(1) プリミティブな方法 挿入時は配列番号順に入れていく [0] [1] [2] [3] [4] [5] 追加 カーソル 追加 カーソル 追加 カーソル 追加 カーソル

キューを配列を使って作る(2) 取り出し時は配列の先頭を削除して、 配列の中身をひとつずつずらす [0] [1] [2] [3] [4] [5] [0] [1] [2] [3] [4] [5] 追加 カーソル [0] [1] [2] [3] [4] [5] 追加 カーソル [0] [1] [2] [3] [4] [5] 追加 カーソル [0] [1] [2] [3] [4] [5] 追加 カーソル [0] [1] [2] [3] [4] [5] 追加 カーソル [0] [1] [2] [3] [4] [5] 追加 カーソル

この方法の問題点 削除するたびに要素の移動が起こる。 効率はO(N)のオーダーで悪くなる 要素が少なければいいけど、多いと、 効率が悪いね。

配列で円環キューを作る(1) 今日の課題でつかうのはこの方法 追加するときは追加カーソルがあるところに追加する 追加したら、追加カーソルを一つずらす [0] [1] [2] [3] [4] [5] 追加 カーソル 追加 カーソル 追加 カーソル 追加 カーソル

配列で円環キューを作る(2) 削除するときは削除カーソルがあるところから削除する 削除したら、削除カーソルを一つずらす [0] [1] [2] [3] [4] [5] [0] [1] [2] [3] [4] [5] [0] [1] [2] [3] [4] [5] [0] [1] [2] [3] [4] [5] 削除 カーソル 削除 カーソル 削除 カーソル 削除 カーソル 追加 カーソル

配列で円環キューを作る(3) 追加カーソルが配列を最後まできたら、 配列の一番初めに戻す。 →ラップアラウンド(最初に戻るの意)といいます。 [0] [1] [2] [3] [4] [5] 削除 カーソル 追加 削除 カーソル 追加 カーソル ※削除も同様

配列で円環キューを作る(4) 追加カーソルと削除カーソルが同じ位置にあるときは、 要素が入っていないことを示す。 [0] [1] [2] [3] [4] [5] 削除 カーソル 追加 カーソル

この方法の効率 効率はO(1)になる。 ただし、少しコードが複雑になる。

円環キューの実装 //円環キューを使って商品を収納するクラス public class ItemQueue { int arrayMax = 5;//配列のサイズ Item[] itemArray = new Item[arrayMax];//商品が入る配列 int addCursol = 0;//追加カーソル int removeCursol =0;//削除カーソル //挿入するメソッド public void insert(Item insertItem){ itemArray[addCursol] = insertItem;//追加カーソルの位置に挿入する addCursol++; //追加カーソルを1増やす if (addCursol >= arrayMax){//配列の最後にきたら addCursol = 0;        //ラップアラウンドする }  //この後削除メソッドは次のページ

円環キューの実装 //前ページの続き。円環キューを使って商品を収納する //商品を削除するメソッド  public Item remove(){ if(addCursol == removeCursol){//商品がない return null;//何も入っていないのでnullを返す }   Item item = itemArray[removeCursol];//削除カーソルのところの商品を取り出す itemArray[removeCursol]=null;//削除カーソルのところの商品を削除する removeCursol++;//削除カーソルを1増やす if (removeCursol >= arrayMax){//配列の最後にきたら removeCursol =0; //ラップアラウンドする return item;//削除した商品を返す }//ItemQueueの終わり

キューのその他の使い道 銀行の待ち行列 プリンタの待ち行列 コンピュータのプロセスの待ち行列 (プライオリティーキュー) etc…

今日考えること② 要求:お金を入れたのをUndoできる自動販売機を考えます。 ①100円,10円,50円の順番でお金を入れる。 (この時点で投入金額は160円) ②Undoを実行すると、最後に入れたお金が戻る。(50円が取り消され、投入金額が110円になる) ③もう一度Undoすると10円が戻る ※実際の自動販売機でこの例のようなケースは、 あまりありませんが、一般のソフトウエアでの Undo機能は重要な機能です。

どちらをデータ構造を利用すべきか スタックVSキュー 考えてみましょう!(簡単ですね。) Undoを実現するには追加と逆順で削除する必要があります。 この場合、スタックを使うべきです。

配列でスタックを作る(1) スタックの実装はキューに比べて簡単です。 スタックへのお金の追加 10 50 100 50 10 50 100 [0] [1] [2] [3] [4] [5] 10 100 追加&削除 カーソル 追加&削除 カーソル 追加&削除 カーソル 追加&削除 カーソル

配列でスタックを作る(2) スタックからお金の削除(Undo) [0] [1] [2] [3] [4] [5] 100 10 [0] [1] 50 100 10 [0] [1] [2] [3] [4] [5] 追加&削除 カーソル 追加&削除 カーソル 追加&削除 カーソル 追加&削除 カーソル 削除は追加カーソルの一つ前を削除します。

スタック 実装コード 簡単なのでここでは取り上げません。 課題を参照してください。 効率 O(1)という非常に高速オーダーで機能します。

スタックのその他の使い道 算術式のパース(解析) XML,HTMLなどの入れ子構造の解析 食堂のトレー置き場 etc

算術式のパース 問題: 3 + 4 * 5 (4 + 5) * (8 - 4) などをコンピュータはどうやって計算するか?

答え コンピュータはそのまま計算できない。 →特別な記法に変換する必要がある。 例) 3 + 4 * 5 → 3 4 5 * + 中置記法 例) 3 + 4 * 5 → 3 4 5 * + 中置記法 後置記法 (逆ポーランド記法)

後置記法で書かれた式を計算する ルール 左から一文字ずつ読む 数字がきたらスタックにつむ 演算子がきたらスタックの上から2つの数字を取り出して演算する 演算したら結果をスタックの上に積む これを式の最後まで繰り返す

後置記法で書かれた式を計算する 計算対象 3 4 5 * + 20 5 23 4 3 スタック

中置記法と後置記法 中置記法 後置記法 A+B-C AB+C- A*B/C AB*C/ A+B*C ABC*+ A*B+C AB*C+ A*B+C*D AB*CD*+ (A+B)*(C-D) AB+CD-* ((A+B)*C)-D AB+C*D-

後置記法と日本語 日本語と語順が同じ。 →日本語とコンピュータは相性がいい。 3 + 4 * 5 3 4 5 * + →3に4と5をかけたものを足す 5 * 8 + 7 * 3 5 8 * 7 3 * + →5と8をかけたものと7と3をかけたものを足す 日本語と語順が同じ。 →日本語とコンピュータは相性がいい。

中置記法を後置記法に変換する ルール 左から一文字ずつ読む 数字がきたら、結果に書き出す かっこがきたら かっこ以外の演算子がきたら 開きかっこの場合→スタックに積む 閉じかっこの場合→開きかっこを見つけるまで、スタックから演算子を取り出して、結果に書き出す かっこ以外の演算子がきたら スタックが空なら→スタックに積む スタックを覗いて、スタック演算子よりも優先順位の低い演算子だったら、結果に書き出す。そうでなければ、スタックに積む 式を最後まで読み取ったら、スタックに入っているものをすべて出力する

中置記法を後置記法に変換する 対象 3 + 4 * 5 出力 3 3 4 3 4 5 * + 出力 3 3 4 3 4 5 * 出力 3 スタック 3 3 4 3 4 5 * + 出力 スタック 3 + 3 4 3 4 5 * * 出力 + 3 3 4 5 3 4 スタック

今日の課題(1) 2種類のプログラムを配ります。 商品を補充、販売するプログラム お金を入れてUndoができるプログラム Item.java ItemQueue.java ItemMain.java お金を入れてUndoができるプログラム Money.java MoneyStack.java MoneyMain.java

今日の課題(2) 配ったプログラムを完成させなさい。 ①ItemQueueクラスのdisplay()メソッドを実装しなさい。 ②MoneyStackクラスのdisplay()メソッドを実装しなさい。

今日の課題(3) ItemQueueクラスのdisplay()メソッドの出力仕様 ---キューの先頭--- 商品製造日:2000/01/01 商品製造日:2000/01/02 商品製造日:2000/01/03 商品製造日:2000/01/04 ---キューの最後--- ※配列をラップアラウンドしてもきちんとした結果が でるようにしてください。

今日の課題(4) MoneyStackクラスのdisplay()メソッドの出力仕様 ---スタックの先頭--- お金:10円 お金:50円 お金:100円 ---スタックの最後---

課題プログラム解説 今日のプログラムは、少しインタラクティブに、コンソール(標準入力)から文字を読み込むプログラムです。 プログラム 文字の 読み込み

Javaでコンソールから文字を読み込む方法 先週のファイルからの入力とほとんど同じやり方でできます。 詳しくは、ソースを熟読した上でTAにご質問を //コンソールから一行読み込んで文字列を返すメソッド public static String readStringFromConsole(){ String buf = null;//読み込んだ文字列を保存する try{ //読み込むためのBufferedReaderオブジェクトをインスタンス化する BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); buf = br.readLine();//一行読み込む }catch(Exception ex){ ex.printStackTrace();//入出力エラーが起きた場合エラーを表示する } return buf;//読み込んだ文字列を返す ここが先週と違う

課題プログラムのUMLクラス図

発展課題 発展課題① 発展課題② 発展課題③(難) 身の回りにあるキュー、スタックを探してみよう! キュー10例、スタック10例あげてください。 発展課題② 今日のプログラムは、配列を超えて挿入したり、何も入っていないときに削除したりするとエラーでプログラムがとまります。これはまずいです。 できない操作をしたときは、「~だからできません」とユーザに教えてあげるプログラムにしましょう。 発展課題③(難) 算術式をパースするプログラムを書いてみよう! 必修課題とは別にソースを添付してください。

提出方法 objprog-08@crew.sfc.keio.ac.jp宛て。 今回はソースのみを送ってください。 (ただし、ItemQueue,MoneyStackだけでよい。) (感想を任意でお願いします。) Subjectはログイン名を必ず書いてください。 ex) t96844ym 余計な[]などをつけないでください。 水曜まで。