進捗置き場

競プロの問題の解説など.大雑把な方針と自分のコードだけ載せてます

STLの勉強 コンテナ

Effective STLのお勉強
第1章コンテナから

コンテナの選択について

コンテナライブラリは、キュー、リスト、スタックのような一般的なデータ構造をプログラマが簡単に実装することを可能とする汎用のクラステンプレートとアルゴリズムのコレクションです。(cppreference.comより)

  • シーケンスコンテナ(vector, string, deque, list)
    シーケンシャルアクセスが可能なデータ構造

  • 連想コンテナ(set, multiset, map, multimap)
    高速に検索可能(O(logn))なソート済みのデータ構造

  • 非順序連想コンテナ
    ハッシュコンテナ

使い分けケース・バイ・ケース

  1. コンテナの任意の位置に新しい要素を挿入する必要がある
    →シーケンスコンテナが必要.連想コンテナは使用不可

  2. どのカテゴリのイテレータが必要か
    → ランダムアクセスイテレータが必要ならvector, deque, string

  3. 挿入または消去が行われるとき,既存のコンテナ要素の移動を避ける必要がある → 連続メモリコンテナはやめとけ

  4. Cと互換性を保ちたい → vectorを使っておけ

コンテナのオブジェクトのコピーについて

コンテナはオブジェクトを格納しているが,そのコンテナが格納しているのは指定したオブジェクトの「コピー」である. すなわち,コピーの負荷が大きいオブジェクトを追加する動作は,パフォーマンスに悪影響を及ぼす.また,オブジェクトの継承が ある場合,基本クラスオブジェクトのコンテナに派生クラスオブジェクトを挿入すると,派生部分がなくなってしまう問題がある.

これらを解決する手段は,オブジェクトのコンテナの代わりに「ポインタ」のコンテナを生成することである.

単一要素メンバ関数より,範囲メンバ関数を使え

v1, v2という2つのベクトルがある.v1をv2の後ろ半分と同じ内容にする簡単な方法を考えよ

以下のような選択肢がある.

  • assign関数を使う
v1.assign(v2.begin() + v2.size() / 2, v2.end());
  • copy関数を使う
v1.clear();
copy(v2.begin() + v2.size() / 2, v2.end(), back_inserter(v1));
  • for文と代入で頑張る
v1.clear();
for(auto ci = v2.begin() + v2.size() / 2; ci != v2.end(); ci++)
    v1.push_back(*ci);

結論はassign関数使ったほうがいいよねっていう話.copyの内部もループがある. insert, erase, assignは覚えておこうね