スライド 1

Similar documents
4-3- 基 C++ に関する知識 オープンソースシステムのソースを解読する上で C++ の知識は必須であるといえる 本カリキュラムでは まずオブジェクト指向に関する Ⅰ. 概要理解を深め クラスの扱い方について学習し STL を使用してアルゴリズムとデータ構造を実装する方法を学習する Ⅱ. 対象専

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Microsoft PowerPoint ppt

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

memo

02: 変数と標準入出力

02: 変数と標準入出力

プログラミング実習I

Microsoft PowerPoint - 6.pptx

Microsoft PowerPoint - 09.pptx

第2回

第3回 配列とリスト

PowerPoint プレゼンテーション

Microsoft PowerPoint - 計算機言語 第7回.ppt

gengo1-11

Sort-of-List-Map(A)

memo

JAVA入門

memo

Boost.Preprocessor でプログラミングしましょう DigitalGhost

Microsoft PowerPoint - prog03.ppt

memo

Green with White Lines

CプログラミングI

(STL) STL 1 (deta structure) (algorithm) (deta structure) 2 STL STL (Standard Template Library) 2.1 STL STL ( ) vector<int> x; for(int i = 0; i < 10;

メソッドのまとめ

基礎プログラミング2015

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

Slide 1

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

JAVA入門

プログラミングI第10回

02: 変数と標準入出力

Microsoft PowerPoint - 05.pptx

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

情報処理Ⅰ演習

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

PowerPoint プレゼンテーション

02: 変数と標準入出力

memo

Taro-リストⅢ(公開版).jtd

Microsoft PowerPoint - ca ppt [互換モード]

02: 変数と標準入出力

PowerPoint プレゼンテーション

Prog1_10th

PowerPoint プレゼンテーション

Taro-ポインタ変数Ⅰ(公開版).j

Microsoft PowerPoint pptx

微分方程式 モデリングとシミュレーション

Microsoft PowerPoint - prog03.ppt

基礎プログラミング2015

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

02: 変数と標準入出力

Microsoft Word - no202.docx

情報処理Ⅰ

Microsoft PowerPoint - 5Chap15.ppt

02: 変数と標準入出力

Microsoft Word - 第5回 基本データ構造2(連結リスト).doc

PowerPoint プレゼンテーション

演算増幅器

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

プログラミング基礎I(再)

C 資料 電脳梁山泊烏賊塾 構造体 C++ の構造体 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 定義と変数宣言 C++ に

Taro-再帰関数Ⅲ(公開版).jtd

Microsoft PowerPoint - prog04.ppt

Taro-リストⅠ(公開版).jtd

JavaプログラミングⅠ

Microsoft PowerPoint - CproNt02.ppt [互換モード]

02: 変数と標準入出力

Microsoft PowerPoint - prog13.ppt

C#の基本2 ~プログラムの制御構造~

02: 変数と標準入出力

関数の中で宣言された変数の有効範囲はその関数の中だけです さっきの rectangle _s で宣言されている変数 s は他の関数では使用できません ( 別の関数で同じ名前の変数を宣言することはできますが 全く別の変数として扱われます このように ある関数の中で宣言されている変数のことをその関数の

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft PowerPoint - lec10.ppt

Microsoft Word - no12.doc

pp2018-pp9base

02: 変数と標準入出力

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdio.h> #define InFile "data.txt" #define OutFile "sorted.txt" #def

Microsoft PowerPoint - 06.pptx

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

プログラム言語及び演習Ⅲ

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

PowerPoint Template

Microsoft PowerPoint - Pro110111

1. 入力した文字列を得る 1.1. 関数 scanf() を使う まずは関数 scanf() を使ったプログラムを作ってみましょう 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: #include<stdio.h> #define SIZE 128 main(

Microsoft Word - no11.docx

Microsoft PowerPoint - prog07.ppt

Taro-最大値探索法の開発(公開版

Microsoft PowerPoint - 12.ppt [互換モード]

プログラミングI第6回

Microsoft PowerPoint pptx

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

人工知能入門

PowerPoint Presentation

講習No.12

02: 変数と標準入出力

Transcription:

今 此処にある C++ ~ テンプレートと STL~

テンプレートの解説 コンテナ イテレータ アルゴリズム アジェンダ

テンプレートとは 型を外部から変更可能にした構文 通常の構文 int max(int a, int b){ return a > b? a : b; テンプレートを使った構文 template <typename T> T max(t a, T b){ return a > b? a : b; 穴埋めコラムテンプレート内で T::A と書いた場合 T::A は変数とみなされる これが typedef とか 内部に定義した struct とかだとコンパイルエラーが出る それを埋めるのが typename というキーワード typename T::A a; と書けば型と見てくれるようになる

define と template の比較 #define の構文 #define max(a, b) ((a)>(b)? (a) : (b)) template の構文 template <typename T> T max(t a, T b){ return a > b? a : b; void hoo(int a, int b){ int c = max(a, b); void hoo(int a, int b){ int c = max(a, b);

define と template の比較展開後のイメージ #defineの展開後 void foo(int a, int b){ int c = a > b? a : b; templateの展開後 int max(int a, int b){ return a > b? a : b; void foo(int a, int b){ int c = max(a, b);

テンプレートの欠点 テンプレート単体ではエラーが出ない実体を定義したとき内部の文法がチェックされる エラーがわかりにくい大量のエラーが発生する可能性がある C++0x の concept はこれを回避する目的がある サイズの肥大化使用した型毎にコードが生成される ロジックをヘッダファイルに書くことになる修正の度に関連するソースすべてにリコンパイルが必要になる

どう使えばよいのか テンプレートとは defineで実装していたマクロの代替 式を関数に変換 ビット幅や整数 実数を可変にした数値型 拡張版 void * 実質的兄弟クラスとしての利用 インライン展開

STL (Standard Template Library) テンプレートを使って構成されたライブラリ 現在のC++ で標準ライブラリとして収録 std 名前空間に属する 代表的なものとして以下のような要素がある コンテナ イテレータ ( 反復子 ) アルゴリズム 関数オブジェクト / 関数アダプタ

物を入れる箱 コンテナ 主に以下のものが提供される 可変長配列 (vector, deque, list) ソート済み連想配列 (set,map) ハッシュによる連想配列 (hash_set/hash_map) 穴埋めコラムハッシュによると書いているが 別にハッシュを使って実装する必要はない これは STL が 要件を満たせば実装方法はなんでもよい という方針だから ( 要件を考えると 実質的にハッシュを用いる事になると思うが ) 上記の理由から TR1 からは unordered_set(map) という名前に変わっている 文字通り 順番に並んでいないというところを強調している

可変長配列 vector/deque/list が相当する 使い方はほぼ同じだが 処理速度やメモリ消費量が違う 型名 vector deque (double ended queue) list 説明 通常の配列とほぼ同じ使い方ができる要素が減ってもメモリが自動解放されない要素が頻繁に挿入 / 削除される場合には向かない キュー / スタック構造に向く先頭 / 末尾の挿入 / 削除は速いが 途中の挿入 / 削除は遅い 要素の挿入 / 削除が速い挿入 / 削除でイテレータが参照を失わない ( そのものの削除以外 ) メモリ消費が最も多く ランダムアクセスできない

可変長配列の関数表 関数名説明 V D L push_back 末尾に要素を追加する pop_back 末尾の要素を削除する push_front 先頭に要素を追加するー pop_front 先頭の要素を削除するー insert 任意の場所に要素を追加する erase 任意の場所から要素を削除する clear すべての要素を削除する operator [] n 番目の要素を得る ー size 要素の個数を得る V:vector D:deque L:list : 速い : 遅いー : 関数がない vector の push_back はメモリ拡張が起こる時遅くなる

vector のサンプルプログラム vector<int> v; for (int i = 0; i < 100; i++){ v.push_back(i); 要素の挿入 push_back を使うと メモリが許す限り挿入が可能 for (int i = 0; i < v.size(); i++){ printf( %d n, v[i]); 要素の参照通常の配列と同じ感覚で使用することができる しかし list の場合は operator [] がないので 別の書き方が必要

イテレータ list の全要素を表示するには以下のように記述する list<int> l; list<int>::iterator it; for(it = l.begin(); it!= l.end(); it++){ printf( %d n, *it); そして vector/dequeも同じように書ける vector<int> v; vector<int>::iterator it; for(it = v.begin(); it!= v.end(); it++){ printf( %d n, *it); ここの書式がほぼ一緒 ループ内部にコンテナの変数名がまったく登場していない

イテレータ シーケンスの各要素の参照の抽象化要は データの集合に対し順番にアクセスする方法 イテレータは以下の要素をもつ 間接参照 (*it) 前進 (it++) 位置の比較 (it1!= it2) C のポインタと互換性をもたせる工夫がある 穴埋めコラム上の説明は外部イテレータの事であり 他に内部イテレータというものもある foreach のように前進とループ終了判定を書かなくていいものが内部イテレータ C# の yield の項目で出てくる反復子は内部イテレータのこと

イテレータと範囲 1. it == v.end() でループを抜ける 2. v.end() の要素はループを通らない 3. 右図のように v.end() の要素は参照してはいけない領域を指している 穴埋めコラム v.end() の内容を参照した場合は未定義である これ以外に要素が 0 なのに pop_back したり 参照が失われたイテレータを操作したりしても未定義であり 例外が出るわけではない 未定義とは 何が起こっても知らんって意味 STL は例外を出さない実装が多い v.begin() v.end() vector<int> v 1 2 3 4 5 ( 範囲外領域 )

for 文で簡潔に書ける なぜ終了点を含まないのか first=last とすることで 空リストを表せる insert で挿入できる場所は 要素の数 +1 ある 穴埋めコラム C# の IEnumerator は Reset と MoveNext で外部イテレータを実装している Reset で取得できる場所は 先頭要素の 1 つ前を想定した場所であり MoveNext を一度行うことで先頭要素を示すことになる サンプルプログラムには最初の MoveNext を無視するフラグが入ってたりする var it = array.reset(); while (it.movenext()){ Console.WriteLine(it.Current());

リバースイテレータ 逆向きに動作するイテレータ ++ で前の要素 -- で次の要素に移動する begin,end の代わりに rbegin,rend を使用する vector<int> v; vector<int>::reverse_iterator it; for(it = v.rbegin(); it!= v.rend(); it++){ printf( %d n, *it); 穴埋めコラム reverse_iterator は iterator にキャストできない 同じ要素を指す iterator に変換したい場合はこう書くとよい it = --rev_it.base(); なお v.rbegin().base() == v.end() が成り立つ

インサートイテレータ = 演算子で値を入れることでコンテナに要素が挿入されるイテレータ 通常のイテレータと違い 前進 (it++) や間接参照 (*it) は意味を持たない 型名 front_insert_iterator back_insert_iterator insert_iterator 説明 push_front を使って挿入する vector では push_front がないため 使えない push_back を使って挿入する insert を使って挿入する

インサートイテレータ インサートイテレータの使用方法 vector<int> v; back_insert_iterator<vector<int> > ins(v); for(int i = 0; I < 10; i++){ // v.push_back(i); と同じ意味 *ins++ = i; 上のサンプルの *ins++ = i は ins = i でも全く問題ない *ins も ins++ も何も処理を行わず自分自身を返すため コンパイル後は全く同じコードが生成されることになる それでも このように書く理由がある

インサートイテレータを使う コピー関数をテンプレートで作成 template<typename A, typename B> void copy(a first, A last, B ins){ for(a it = first; it!= last; it++){ *ins++ = *it; 配列を渡す場合は先頭と末尾を渡し 受け取る時はインサートイテレータを考慮した構文である 使い方例 int a[5], b[5]; copy(a, a + 5, b); // for(int *it = a; it!= a + 5; it++){ // *b++ = *it; // vector<int> v; back_insert_iterator bi(v); copy(a, a + 5, bi); // for(int *it = a; it!= a + 5; it++){ // *bi++ = *it; //

アルゴリズム テンプレートを使ったライブラリ集 今回作った max,copy も収録されている シーケンスに対する操作を行う関数が多いその際 イテレータを使って範囲を渡す 穴埋めコラムアルゴリズムの中にはコールバック関数を伴うものもある 通常は関数ポインタを渡すが 関数の呼び出し風に記述できれば何でもよい 簡単な処で #define のマクロが思いつくが これは型を持たないので NG である そこで クラスを作り operator() をオーバーロードしたものを用意する これを関数オブジェクトと言い インライン展開されるので高速に動作する 現在は かなり野暮ったい構文になるのでなかなか使いづらいが C++0x のラムダ式が加わると 直観的な記述が可能になる

アルゴリズムの関数の抜粋 関数名 find count copy fill reverse random_shuffle sort lower_bound binary_search next_permutation swap max 説明 [first,last) 区域からvalueと同値のイテレータを返す [first,last) 区域からvalueと同値の要素の数を数える [first,last) 区域をinsert_iteratorにコピーする [first, last) 区域にvalueを代入する [first, last) 区域の値を逆にする [first, last) 区域をランダムに入れ替える [first, last) 区域をソートする [first, last) 区域からvalueと同値かそれ未満のイテレータを返す [first, last) 区域からバイナリサーチを行い 要素があるか返す [first, last) 区域を次の順列にする AとBを入れ替える AとBの大きい方を返す

最後に STL はあらゆるものを抽象化しようとしている 紹介しきれなかった機能で便利なもの map ストリーム string でもまだまだあると便利なものは多い Boost に続く